<!DOCTYPE html>
<html lang="en-US" dir="ltr">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>安装Nvidia驱动 | VitePress</title>
    <meta name="description" content="A VitePress site">
    <link rel="preload stylesheet" href="/notebook/assets/style.3dbfd0c2.css" as="style">
    
    <script type="module" src="/notebook/assets/app.8aaa4cbe.js"></script>
    <link rel="preload" href="/notebook/assets/inter-roman-latin.2ed14f66.woff2" as="font" type="font/woff2" crossorigin="">
    <link rel="modulepreload" href="/notebook/assets/chunks/framework.1336c4e5.js">
    <link rel="modulepreload" href="/notebook/assets/chunks/theme.20cddc0c.js">
    <link rel="modulepreload" href="/notebook/assets/Linux_Linux进阶.md.188ef7b4.lean.js">
    <script id="check-dark-light">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
  </head>
  <body>
    <div id="app"><div class="Layout" data-v-255ec12d><!--[--><!--]--><!--[--><span tabindex="-1" data-v-ae3e3f51></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-ae3e3f51> Skip to content </a><!--]--><!----><header class="VPNav" data-v-255ec12d data-v-7e5bc4a5><div class="VPNavBar has-sidebar" data-v-7e5bc4a5 data-v-0937f67c><div class="container" data-v-0937f67c><div class="title" data-v-0937f67c><div class="VPNavBarTitle has-sidebar" data-v-0937f67c data-v-86d1bed8><a class="title" href="/notebook/" data-v-86d1bed8><!--[--><!--]--><!--[--><img class="VPImage logo" src="/notebook/Vue.png" alt data-v-8426fc1a><!--]--><!--[-->任硕的文档<!--]--><!--[--><!--]--></a></div></div><div class="content" data-v-0937f67c><div class="curtain" data-v-0937f67c></div><div class="content-body" data-v-0937f67c><!--[--><!--]--><div class="VPNavBarSearch search" style="--vp-meta-key:&#39;Meta&#39;;" data-v-0937f67c><!--[--><!----><div id="docsearch"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><svg class="DocSearch-Search-Icon" width="20" height="20" viewBox="0 0 20 20" aria-label="search icon"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-0937f67c data-v-7f418b0f><span id="main-nav-aria-label" class="visually-hidden" data-v-7f418b0f>Main Navigation</span><!--[--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-7f418b0f data-v-a7b5672a><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-a7b5672a><span class="text" data-v-a7b5672a><!----><span data-v-a7b5672a>Java学前端</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-a7b5672a><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-a7b5672a><div class="VPMenu" data-v-a7b5672a data-v-e7ea1737><div class="items" data-v-e7ea1737><!--[--><!--[--><div class="VPMenuGroup" data-v-e7ea1737 data-v-69e747b5><!----><!--[--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/Java%E5%AD%A6%E5%89%8D%E7%AB%AF/HTML+JS.html" data-v-2f2cfafc><!--[-->HTML+JS<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/Java%E5%AD%A6%E5%89%8D%E7%AB%AF/CSS.html" data-v-2f2cfafc><!--[-->CSS<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/Java%E5%AD%A6%E5%89%8D%E7%AB%AF/Vue2+%E7%BB%84%E4%BB%B6.html" data-v-2f2cfafc><!--[-->Vue2+组件<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/Java%E5%AD%A6%E5%89%8D%E7%AB%AF/Vue3+%E7%BB%84%E4%BB%B6.html" data-v-2f2cfafc><!--[-->Vue3+组件<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/Java%E5%AD%A6%E5%89%8D%E7%AB%AF/React.html" data-v-2f2cfafc><!--[-->React<!--]--></a></div><!--]--><!--]--></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-7f418b0f data-v-a7b5672a><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-a7b5672a><span class="text" data-v-a7b5672a><!----><span data-v-a7b5672a>软件测试</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-a7b5672a><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-a7b5672a><div class="VPMenu" data-v-a7b5672a data-v-e7ea1737><div class="items" data-v-e7ea1737><!--[--><!--[--><div class="VPMenuGroup" data-v-e7ea1737 data-v-69e747b5><!----><!--[--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/%E6%B5%8B%E8%AF%95%E5%9F%BA%E7%A1%80.html" data-v-2f2cfafc><!--[-->测试基础<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/%E5%8E%8B%E5%8A%9B%E6%B5%8B%E8%AF%95.html" data-v-2f2cfafc><!--[-->压力测试<!--]--></a></div><!--]--><!--]--></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-7f418b0f data-v-a7b5672a><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-a7b5672a><span class="text" data-v-a7b5672a><!----><span data-v-a7b5672a>多线程</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-a7b5672a><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-a7b5672a><div class="VPMenu" data-v-a7b5672a data-v-e7ea1737><div class="items" data-v-e7ea1737><!--[--><!--[--><div class="VPMenuGroup" data-v-e7ea1737 data-v-69e747b5><!----><!--[--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/%E5%B9%B6%E5%8F%91%20&amp;%20%E5%A4%9A%E7%BA%BF%E7%A8%8B/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-2f2cfafc><!--[-->基础篇<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/%E5%B9%B6%E5%8F%91%20&amp;%20%E5%A4%9A%E7%BA%BF%E7%A8%8B/%E5%B9%B6%E5%8F%91%E5%AE%8C%E5%96%84.html" data-v-2f2cfafc><!--[-->进阶篇<!--]--></a></div><!--]--><!--]--></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-7f418b0f data-v-a7b5672a><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-a7b5672a><span class="text" data-v-a7b5672a><!----><span data-v-a7b5672a>开发工具</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-a7b5672a><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-a7b5672a><div class="VPMenu" data-v-a7b5672a data-v-e7ea1737><div class="items" data-v-e7ea1737><!--[--><!--[--><div class="VPMenuGroup" data-v-e7ea1737 data-v-69e747b5><!----><!--[--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/IDEA/Chrome.html" data-v-2f2cfafc><!--[-->Chrome<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/IDEA/IDEA%E5%9F%BA%E7%A1%80.html" data-v-2f2cfafc><!--[-->IDEA基础<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/IDEA/IDEA%E6%8F%92%E4%BB%B6.html" data-v-2f2cfafc><!--[-->IDEA插件<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/IDEA/VS%20Code.html" data-v-2f2cfafc><!--[-->VS Code<!--]--></a></div><!--]--><!--]--></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-7f418b0f data-v-a7b5672a><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-a7b5672a><span class="text" data-v-a7b5672a><!----><span data-v-a7b5672a>消息中间件</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-a7b5672a><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-a7b5672a><div class="VPMenu" data-v-a7b5672a data-v-e7ea1737><div class="items" data-v-e7ea1737><!--[--><!--[--><div class="VPMenuGroup" data-v-e7ea1737 data-v-69e747b5><!----><!--[--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6/RabbitMQ.html" data-v-2f2cfafc><!--[-->RabbitMQ<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6/RocketMQ.html" data-v-2f2cfafc><!--[-->RocketMQ<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6/Kafka.html" data-v-2f2cfafc><!--[-->Kafka<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-69e747b5 data-v-2f2cfafc><a class="VPLink link" href="/notebook/%E6%B6%88%E6%81%AF%E4%B8%AD%E9%97%B4%E4%BB%B6/Canal.html" data-v-2f2cfafc><!--[-->Canal<!--]--></a></div><!--]--><!--]--></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-0937f67c data-v-f6a63727><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title="toggle dark mode" aria-checked="false" data-v-f6a63727 data-v-82b282f1 data-v-f3c41672><span class="check" data-v-f3c41672><span class="icon" data-v-f3c41672><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-82b282f1><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-82b282f1><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-0937f67c data-v-0394ad82 data-v-7bc22406><!--[--><a class="VPSocialLink no-icon" href="https://github.com/renshuo123/renshuo123.github.io" aria-label="github" target="_blank" rel="noopener" data-v-7bc22406 data-v-f80f8133><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></a><a class="VPSocialLink no-icon" href="#" aria-label="twitter" target="_blank" rel="noopener" data-v-7bc22406 data-v-f80f8133><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Twitter</title><path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/></svg></a><a class="VPSocialLink no-icon" href="https://github.com/" aria-label target="_blank" rel="noopener" data-v-7bc22406 data-v-f80f8133><svg t="1676028692954" class="icon" ...</path></svg></a><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-0937f67c data-v-40855f84 data-v-a7b5672a><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-a7b5672a><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="icon" data-v-a7b5672a><circle cx="12" cy="12" r="2"></circle><circle cx="19" cy="12" r="2"></circle><circle cx="5" cy="12" r="2"></circle></svg></button><div class="menu" data-v-a7b5672a><div class="VPMenu" data-v-a7b5672a data-v-e7ea1737><!----><!--[--><!--[--><!----><div class="group" data-v-40855f84><div class="item appearance" data-v-40855f84><p class="label" data-v-40855f84>Appearance</p><div class="appearance-action" data-v-40855f84><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title="toggle dark mode" aria-checked="false" data-v-40855f84 data-v-82b282f1 data-v-f3c41672><span class="check" data-v-f3c41672><span class="icon" data-v-f3c41672><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-82b282f1><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-82b282f1><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div></div></div><div class="group" data-v-40855f84><div class="item social-links" data-v-40855f84><div class="VPSocialLinks social-links-list" data-v-40855f84 data-v-7bc22406><!--[--><a class="VPSocialLink no-icon" href="https://github.com/renshuo123/renshuo123.github.io" aria-label="github" target="_blank" rel="noopener" data-v-7bc22406 data-v-f80f8133><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></a><a class="VPSocialLink no-icon" href="#" aria-label="twitter" target="_blank" rel="noopener" data-v-7bc22406 data-v-f80f8133><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Twitter</title><path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/></svg></a><a class="VPSocialLink no-icon" href="https://github.com/" aria-label target="_blank" rel="noopener" data-v-7bc22406 data-v-f80f8133><svg t="1676028692954" class="icon" ...</path></svg></a><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-0937f67c data-v-e5dd9c1c><span class="container" data-v-e5dd9c1c><span class="top" data-v-e5dd9c1c></span><span class="middle" data-v-e5dd9c1c></span><span class="bottom" data-v-e5dd9c1c></span></span></button></div></div></div></div><!----></header><div class="VPLocalNav reached-top" data-v-255ec12d data-v-5cfd5582><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-5cfd5582><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="menu-icon" data-v-5cfd5582><path d="M17,11H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,11,17,11z"></path><path d="M21,7H3C2.4,7,2,6.6,2,6s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,7,21,7z"></path><path d="M21,15H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,15,21,15z"></path><path d="M17,19H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,19,17,19z"></path></svg><span class="menu-text" data-v-5cfd5582>Menu</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-5cfd5582 data-v-18201f51><button data-v-18201f51>Return to top</button><!----></div></div><aside class="VPSidebar" data-v-255ec12d data-v-845b8fc6><div class="curtain" data-v-845b8fc6></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-845b8fc6><span class="visually-hidden" id="sidebar-aria-label" data-v-845b8fc6> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>Java</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Java/Java%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Java基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Java/Java%E6%96%B0%E7%89%B9%E6%80%A7.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Java新特性</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Java/Java%E8%BF%9B%E9%98%B6.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Java进阶</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Java/Java%E9%9B%86%E5%90%88.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Java集合</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Java/Java%E9%AB%98%E7%BA%A7.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Java高级</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible has-active" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>Linux</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Linux/Linux%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Linux基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Linux/Linux%E8%BF%9B%E9%98%B6.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Linux新特性</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Linux/Shell.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Shell脚本</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Linux/%E5%AE%9E%E7%94%A8%E8%84%9A%E6%9C%AC.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>实用脚本</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Linux/%E8%BD%AF%E4%BB%B6%E9%83%A8%E7%BD%B2.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>软件部署</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>Nginx</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Nginx/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>基础篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Nginx/%E8%BF%9B%E9%98%B6%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>进阶篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Nginx/%E5%AE%9E%E6%88%98%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>实战篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Nginx/%E9%9D%A2%E8%AF%95%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>面试篇</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>SSM</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/SSM/Maven.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Maven</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/SSM/Spring.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Spring</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/SSM/SpringMVC.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>SpringMVC</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/SSM/SpringBatch.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>SpringBatch</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>SpringBoot</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/3%E3%80%81SpringBoot/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>基础篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/3%E3%80%81SpringBoot/%E5%BA%94%E7%94%A8%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>应用篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/3%E3%80%81SpringBoot/%E6%96%B0%E7%89%B9%E6%80%A7.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>新特性</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/3%E3%80%81SpringBoot/%E8%BF%90%E7%BB%B4&amp;%E5%8E%9F%E7%90%86.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>运维&原理</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>SpringCloud</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/4%E3%80%81%E5%BE%AE%E6%9C%8D%E5%8A%A1/%E8%BF%9B%E9%98%B6.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>SpringCloud</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/4%E3%80%81%E5%BE%AE%E6%9C%8D%E5%8A%A1/%E5%BF%85%E5%A4%87/Sentinel.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Sentinel</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>SpringSecurity</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/4%E3%80%81%E5%BE%AE%E6%9C%8D%E5%8A%A1/SpringSecurity/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>SpringSecurity基础篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/4%E3%80%81%E5%BE%AE%E6%9C%8D%E5%8A%A1/SpringSecurity/%E8%BF%9B%E9%98%B6%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>SpringSecurity进阶篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/4%E3%80%81%E5%BE%AE%E6%9C%8D%E5%8A%A1/SpringSecurity/%E9%AB%98%E7%BA%A7%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>SpringSecurity高级篇</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>Mybatis & MybatisPlus</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Mybatis&amp;MybatisPlus/Mybatis.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Mybatis</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Mybatis&amp;MybatisPlus/MybatisPlus.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>MybatisPlus</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/Mybatis&amp;MybatisPlus/JPA.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>JPA</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>Git & ChatGPT</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/5%E3%80%81%E8%BF%90%E7%BB%B4/Git.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Git</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/5%E3%80%81%E8%BF%90%E7%BB%B4/Github.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Github</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/5%E3%80%81%E8%BF%90%E7%BB%B4/ChatGPT.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>ChatGPT</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/5%E3%80%81%E8%BF%90%E7%BB%B4/Jenkins.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Jenkins</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/5%E3%80%81%E8%BF%90%E7%BB%B4/Netty.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Netty</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>数据库</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>MySQL</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/MySQL/MySQL%E6%A0%B8%E5%BF%83/%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>MySQL基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/MySQL/MySQL%E6%A0%B8%E5%BF%83/%E8%BF%9B%E9%98%B6.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>MySQL进阶</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/MySQL/MySQL%E6%A0%B8%E5%BF%83/%E4%BC%98%E5%8C%96.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>MySQL优化</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/MySQL/MySQL%E6%A0%B8%E5%BF%83/%E8%AE%BE%E8%AE%A1.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>MySQL设计</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/MySQL/MySQL%E6%A0%B8%E5%BF%83/%E8%BF%90%E7%BB%B4.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>MySQL运维</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/MySQL/%E5%88%86%E5%BA%93%E5%88%86%E8%A1%A8.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>分库分表</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>Redis</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/Redis%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Redis基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/Redis%E4%BC%98%E5%8C%96.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Redis优化</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/Redis%E5%8E%9F%E7%90%86.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Redis原理</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/Redis%E9%AB%98%E7%BA%A7.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Redis高级</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/Redis%E5%AE%9E%E6%88%98.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Redis实战</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/%E6%9C%AC%E5%9C%B0%E7%BC%93%E5%AD%98.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>本地缓存</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>MongoDB</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/MongoDB/%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>MongoDB基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/MongoDB/%E6%95%B4%E5%90%88.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>MongoDB进阶</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>ElasticSearch</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/ElasticSearch/1%E3%80%81ES%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>ES基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/ElasticSearch/3%E3%80%81ES%E9%AB%98%E7%BA%A7.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>ES高级</p><!--]--></a><!----></div><!----></div><!--]--></div></section><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/influxdb.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>InfluxDB</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/2%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93/Neo4j.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Neo4j</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>高并发 & 秒杀 & 分布式</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E4%B8%89%E9%AB%98/%E5%88%86%E5%B8%83%E5%BC%8F.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>分布式理论</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/4%E3%80%81%E5%BE%AE%E6%9C%8D%E5%8A%A1/%E5%BF%85%E5%A4%87/%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>分布式锁</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E4%B8%89%E9%AB%98/%E7%A7%92%E6%9D%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>秒杀</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E4%B8%89%E9%AB%98/%E9%AB%98%E5%8F%AF%E7%94%A8.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>高可用</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E4%B8%89%E9%AB%98/%E9%AB%98%E5%B9%B6%E5%8F%91.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>高并发</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>云原生</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E4%BA%91%E5%8E%9F%E7%94%9F/Docker.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Docker</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E4%BA%91%E5%8E%9F%E7%94%9F/K8S.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>K8S</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>可视化 & 监控</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E5%8F%AF%E8%A7%86%E5%8C%96%20&amp;%20%E7%9B%91%E6%8E%A7/%E7%9B%91%E6%8E%A7%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>监控基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E5%8F%AF%E8%A7%86%E5%8C%96%20&amp;%20%E7%9B%91%E6%8E%A7/%E7%9B%91%E6%8E%A7%E8%BF%9B%E9%98%B6.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>监控进阶</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E5%8F%AF%E8%A7%86%E5%8C%96%20&amp;%20%E7%9B%91%E6%8E%A7/%E5%8F%AF%E8%A7%86%E5%8C%96%E5%A4%A7%E5%B1%8F.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>可视化大屏</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E5%8F%AF%E8%A7%86%E5%8C%96%20&amp;%20%E7%9B%91%E6%8E%A7/Zabbix.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Zabbix</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>学前端</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>HTML+CSS</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/1%E3%80%81HTML+CSS/HTML%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>HTML基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/1%E3%80%81HTML+CSS/CSS%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>CSS基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/1%E3%80%81HTML+CSS/%E7%BD%91%E9%A1%B5%E8%BF%9B%E9%98%B6.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>网页进阶</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>JS+TS</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/2%E3%80%81JS+TS/JS%20%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>JS基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/2%E3%80%81JS+TS/JS%20%E8%BF%9B%E9%98%B6.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>JS进阶</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/2%E3%80%81JS+TS/ES6%20%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>ES6基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/2%E3%80%81JS+TS/ES6%20%E8%BF%9B%E9%98%B6.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>ES6进阶</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/2%E3%80%81JS+TS/TypeScript.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>TS基础</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>NodeJS</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/4%E3%80%81Node/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Node基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/4%E3%80%81Node/%E8%BF%9B%E9%98%B6%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Node进阶</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/4%E3%80%81Node/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>项目实战</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>Vue</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/3%E3%80%81Vue/Vue3/Vue3%E8%BF%9B%E9%98%B6.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Vue3进阶</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/3%E3%80%81Vue/Vue3/Vue3%E9%AB%98%E7%BA%A7.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Vue3高级</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/3%E3%80%81Vue/Vue3/Vue3%E6%96%B0%E8%AF%AD%E6%B3%95.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>Vue3新语法</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/3%E3%80%81Vue/Vue2/Vue2%E9%A1%B9%E7%9B%AE.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>项目实战</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>小程序</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/5%E3%80%81%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>小程序基础</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/5%E3%80%81%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%B0%8F%E7%A8%8B%E5%BA%8F%E4%BC%98%E5%8C%96.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>小程序优化</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/5%E3%80%81%E5%B0%8F%E7%A8%8B%E5%BA%8F/uniapp.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>uniapp</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/1%E3%80%81%E5%AD%A6%E5%89%8D%E7%AB%AF/5%E3%80%81%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%B0%8F%E7%A8%8B%E5%BA%8F%E9%A1%B9%E7%9B%AE.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>项目实战</p><!--]--></a><!----></div><!----></div><!--]--></div></section><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>计算机基础</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>数据结构</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>操作系统</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>设计模式</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E7%BD%91%E7%BB%9C%E5%9F%BA%E7%A1%80.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>计算机网络</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/UML.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>UML</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/%E7%AE%97%E6%B3%95/LeetCode.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>LeetCode</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0 collapsible collapsed" data-v-845b8fc6 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h2 class="text" data-v-9b797284>项目实战</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>云尚办公</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E4%BA%91%E5%B0%9A%E5%8A%9E%E5%85%AC/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>基础篇</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>小兔鲜</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E5%B0%8F%E5%85%94%E9%B2%9C/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>基础篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E5%B0%8F%E5%85%94%E9%B2%9C/%E8%BF%9B%E9%98%B6%E7%AF%871.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>进阶篇1</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E5%B0%8F%E5%85%94%E9%B2%9C/%E8%BF%9B%E9%98%B6%E7%AF%872.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>进阶篇2</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>地图</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E7%99%BE%E5%BA%A6%E5%9C%B0%E5%9B%BE/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>基础篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E7%99%BE%E5%BA%A6%E5%9C%B0%E5%9B%BE/%E8%BF%9B%E9%98%B6%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>进阶篇</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>苍穹外卖</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E8%8B%8D%E7%A9%B9%E5%A4%96%E5%8D%96/%E8%BF%9B%E9%98%B6%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>进阶篇</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible collapsed" data-v-9b797284 data-v-9b797284><div class="item" role="button" tabindex="0" data-v-9b797284><div class="indicator" data-v-9b797284></div><h3 class="text" data-v-9b797284>黑马头条</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-9b797284><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-9b797284><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E9%BB%91%E9%A9%AC%E5%A4%B4%E6%9D%A1/%E5%9F%BA%E7%A1%80%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>基础篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E9%BB%91%E9%A9%AC%E5%A4%B4%E6%9D%A1/%E8%BF%9B%E9%98%B6%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>进阶篇</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E9%BB%91%E9%A9%AC%E5%A4%B4%E6%9D%A1/%E8%BF%9B%E9%98%B6%E7%AF%872.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>进阶篇2</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E9%BB%91%E9%A9%AC%E5%A4%B4%E6%9D%A1/%E9%AB%98%E7%BA%A7%E7%AF%87.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>高级篇</p><!--]--></a><!----></div><!----></div><!--]--></div></section><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E6%94%AF%E4%BB%98.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>支付</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/%E9%A1%B9%E7%9B%AE%E6%8E%A8%E8%8D%90.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>项目推荐</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-845b8fc6><section class="VPSidebarItem level-0" data-v-845b8fc6 data-v-9b797284><!----><div class="items" data-v-9b797284><!--[--><div class="VPSidebarItem level-1 is-link" data-v-9b797284 data-v-9b797284><div class="item" data-v-9b797284><div class="indicator" data-v-9b797284></div><a class="VPLink link link" href="/notebook/team.html" data-v-9b797284><!--[--><p class="text" data-v-9b797284>团队成员</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-255ec12d data-v-669faec9><div class="VPDoc has-sidebar has-aside" data-v-669faec9 data-v-6b87e69f><!--[--><!--]--><div class="container" data-v-6b87e69f><div class="aside" data-v-6b87e69f><div class="aside-curtain" data-v-6b87e69f></div><div class="aside-container" data-v-6b87e69f><div class="aside-content" data-v-6b87e69f><div class="VPDocAside" data-v-6b87e69f data-v-3f215769><!--[--><!--]--><!--[--><!--]--><div class="VPDocAsideOutline" data-v-3f215769 data-v-ff0f39c8><div class="content" data-v-ff0f39c8><div class="outline-marker" data-v-ff0f39c8></div><div class="outline-title" data-v-ff0f39c8>On this page</div><nav aria-labelledby="doc-outline-aria-label" data-v-ff0f39c8><span class="visually-hidden" id="doc-outline-aria-label" data-v-ff0f39c8> Table of Contents for current page </span><ul class="root" data-v-ff0f39c8 data-v-d0ee3533><!--[--><!--]--></ul></nav></div></div><!--[--><!--]--><div class="spacer" data-v-3f215769></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-6b87e69f><div class="content-container" data-v-6b87e69f><!--[--><!--]--><!----><main class="main" data-v-6b87e69f><div style="position:relative;" class="vp-doc _notebook_Linux_Linux%E8%BF%9B%E9%98%B6" data-v-6b87e69f><div><h1 id="安装nvidia驱动" tabindex="-1">安装Nvidia驱动 <a class="header-anchor" href="#安装nvidia驱动" aria-label="Permalink to &quot;安装Nvidia驱动&quot;">​</a></h1><p><a href="https://blog.csdn.net/weixin_44348719/article/details/125049064" target="_blank" rel="noreferrer">(180条消息) Ubuntu18.04安装Nvidia驱动【全网不坑，超全步骤】（亲测～）_ubuntu安装nvidia显卡驱动_心清似水淡若云、的博客-CSDN博客</a></p><h1 id="效果酷炫命令" tabindex="-1">效果酷炫命令 <a class="header-anchor" href="#效果酷炫命令" aria-label="Permalink to &quot;效果酷炫命令&quot;">​</a></h1><p>想想电影黑客帝国中的画面，估计很多人都会叹为观止。</p><p>其实只要会用 Linux 操作系统，就可以实现电脑屏幕的字符串雨了！是不是很高大上呢！</p><p>今天将介绍 10 个 Linux 系统的操作指令，都能实现十分酷炫的效果，绝对令人叹为观止！废话不多说，直接进入主题！</p><h2 id="cmatrix-黑客帝国" tabindex="-1">cmatrix 黑客帝国 <a class="header-anchor" href="#cmatrix-黑客帝国" aria-label="Permalink to &quot;cmatrix 黑客帝国&quot;">​</a></h2><p>这个就很酷，有《黑客帝国》那种矩阵风格的动画效果。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sudo apt-get install cmatrix</span></span></code></pre></div><p>接下来就是见证奇迹的时刻：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_gif/s4IVctYyOhh8tW962ttRT7hEebnVtHIatbDaz6zXXAVx4tKiaOfnyR97ok4qTxfo3H5PygY9GzJYIWPHnI5DBlg/640?wx_fmt=gif&amp;wxfrom=5&amp;wx_lazy=1" alt="图片"></p><h2 id="sl-小火车来喽" tabindex="-1">sl 小火车来喽 <a class="header-anchor" href="#sl-小火车来喽" aria-label="Permalink to &quot;sl  小火车来喽&quot;">​</a></h2><p>运行结果是一辆呼啸而过的火车，安装命令如下：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sudo apt-get install sl</span></span></code></pre></div><p>运行结果如下：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_gif/s4IVctYyOhh8tW962ttRT7hEebnVtHIa3ARibiamWUd10DqIqulFJiaBqFsthoogtV28s9aka46SpTuyElVExENZw/640?wx_fmt=gif&amp;wxfrom=5&amp;wx_lazy=1" alt="图片"></p><h2 id="htop-任务管理器" tabindex="-1">htop 任务管理器 <a class="header-anchor" href="#htop-任务管理器" aria-label="Permalink to &quot;htop 任务管理器&quot;">​</a></h2><p>htop 是 Linux 操作系统的图形化性能检测工具，如果类比的话相当于 Windows 操作系统的任务管理器。安装命令如下</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sudo apt-get install htop</span></span></code></pre></div><p>运行出来的结果是绿色的界面，同时动态的检测显示：</p><img src="https://mmbiz.qpic.cn/mmbiz_gif/s4IVctYyOhh8tW962ttRT7hEebnVtHIaMNGB6U9dZ9PgoDZ2lwnrHnKTxOMIGTB3nq6gHBhAc5vSJ1I1icMVvvw/640?wx_fmt=gif&amp;wxfrom=5&amp;wx_lazy=1" alt="图片" style="zoom:50%;"><h2 id="hollywood-装逼" tabindex="-1">hollywood 装逼 <a class="header-anchor" href="#hollywood-装逼" aria-label="Permalink to &quot;hollywood 装逼&quot;">​</a></h2><p>说实话这个命令可能就是抖音里很火的那个，你眼中的程序猿 VS 现实中的程序猿。高大上仪表盘，假装自己日理万机，宵衣旰食。听起来是不是很不错。Dustin Kirkland 利用一个长途飞行的时间，编写了这个炫酷、有趣但也没什么实际作用的软件。 在其它 Linux 发行版中，可以通过以下命令安装。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sudo apt-add-repository ppa:hollywood/ppa</span></span>
<span class="line"><span style="color:#A6ACCD;">sudo apt-get install hollywood</span></span>
<span class="line"><span style="color:#A6ACCD;">sudo apt-get install byobu</span></span></code></pre></div><p>然后通过<code>hollywood</code>这个命令即可欣赏到一个炫酷的界面</p><p><img src="https://mmbiz.qpic.cn/mmbiz_gif/s4IVctYyOhh8tW962ttRT7hEebnVtHIa0mYY9FORQ413BiaGabdYrkl57Z8OPtv5QFNF56ibRJhphzHib3Vb8IhZQ/640?wx_fmt=gif&amp;wxfrom=5&amp;wx_lazy=1" alt="图片"></p><h2 id="cal-输出年月" tabindex="-1">cal 输出年月 <a class="header-anchor" href="#cal-输出年月" aria-label="Permalink to &quot;cal 输出年月&quot;">​</a></h2><p>cal 命令是 Linux 系统命令行的日历可视化指令，输入对应的年月，就可以打印出来对应的日历表。例如查询 2020 年 9 月的日历，执行命令如下：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">cal 9 2020</span></span></code></pre></div><p>运行截图如下：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_gif/s4IVctYyOhh8tW962ttRT7hEebnVtHIasq5xbC9AATicEalY28xwvxAEDRyYNKNNELfhu19V9uV7VqGfB2JPHsA/640?wx_fmt=gif&amp;wxfrom=5&amp;wx_lazy=1" alt="图片"></p><h2 id="fortune-来一句笑话" tabindex="-1">fortune 来一句笑话 <a class="header-anchor" href="#fortune-来一句笑话" aria-label="Permalink to &quot;fortune 来一句笑话&quot;">​</a></h2><p>输出一句话，有笑话，名言什么的 （还有唐诗宋词）。软件包安装：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sudo apt-get install fortune</span></span></code></pre></div><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/BFibC8wtke3u3KIlpzRpxCN8hAoicFfLSPBgA6W9cnBwtjQtEvYy2GNicLvDcxWlBibibib00p0Q8fGiaeurTzMC6oJnA/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"> 这些都是英文的，如果你想看中国的唐诗三百首，则需要再安装：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sudo apt-get install fortune-zh</span></span></code></pre></div><p>来多执行几次<code>fortune-zh</code>，可以看到不同的唐诗：</p><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/BFibC8wtke3u3KIlpzRpxCN8hAoicFfLSPeCfgTeHs9xf3Pica7qT59fWyia5LZJLP2hRxmQuzGekF5kOpHibPMUiaTg/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><h2 id="cowsay-打印牛羊等动物" tabindex="-1">cowsay 打印牛羊等动物 <a class="header-anchor" href="#cowsay-打印牛羊等动物" aria-label="Permalink to &quot;cowsay 打印牛羊等动物&quot;">​</a></h2><p>cowsay 命令可以打印出来一头牛，并且可以指定让这头牛说任意的话语，安装命令如下：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sudo apt-get install cowsay</span></span></code></pre></div><p>比如让这头牛说“Hello，world”，执行以下命令：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">cowsay &quot;Hello,world&quot;</span></span></code></pre></div><p>执行结果如下所示：</p><img src="https://mmbiz.qpic.cn/mmbiz_png/s4IVctYyOhh8tW962ttRT7hEebnVtHIaQMAlGCYWIudUEFWLT1eSTicZ5GrfOmxic7ib0rThuE0CF5BQNmDso8T6w/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片" style="zoom:67%;"><p>还有一种骚操作是 <strong>cowsay -l</strong> 查看其它动物的名字，然后 <strong>-f</strong> 跟上动物名，如：</p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/BFibC8wtke3u3KIlpzRpxCN8hAoicFfLSPjUY4nIdHQtoC793Rc9hyYe0490QicJYWkibD6Obgibl1E5f7VmeDUtB1Q/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片" style="zoom:67%;"><h2 id="aafire-燃烧的火" tabindex="-1">aafire 燃烧的火 <a class="header-anchor" href="#aafire-燃烧的火" aria-label="Permalink to &quot;aafire 燃烧的火&quot;">​</a></h2><p>aafire 终端命令可以将字符串像火焰一样的燃烧地输出。安装命令如下：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sudo apt-get install libaa-bin</span></span></code></pre></div><p>终端执行 aafire 指令，看效果：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_gif/s4IVctYyOhh8tW962ttRT7hEebnVtHIaQvfzRIgjMllFfiaB9fHXtYicx0Np5MsO02ibQXfteBWLm2PttrSz4kkhw/640?wx_fmt=gif&amp;wxfrom=5&amp;wx_lazy=1" alt="图片"></p><h2 id="yes-死循环输出" tabindex="-1">yes 死循环输出 <a class="header-anchor" href="#yes-死循环输出" aria-label="Permalink to &quot;yes 死循环输出&quot;">​</a></h2><p>yes 命令为 Linux 系统的自带命令，只需要直接在终端输入即可，yes 指令的功能是持续地输出指定的字符串。我们试试在 Linux 系统的终端持续输出“hello，world”字符串：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">yes hello,world</span></span></code></pre></div><p>执行效果如下：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/s4IVctYyOhh8tW962ttRT7hEebnVtHIaa4pZ913wWKuxibv3iaPe6NGDBQBXZu73YttfeqAa4HjXicEeTELd6aQgQ/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>只要系统运行，就会持续输出指定的字符串，输入 Ctrl+c 时停止输出。</p><h2 id="bastet-俄罗斯方块" tabindex="-1">bastet 俄罗斯方块 <a class="header-anchor" href="#bastet-俄罗斯方块" aria-label="Permalink to &quot;bastet 俄罗斯方块&quot;">​</a></h2><p>使用 bastet 命令可以在 Linux 系统下玩俄罗斯方块，安装命令如下：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sudo apt-get install bastet</span></span></code></pre></div><p>运行结果如下：</p><img src="https://mmbiz.qpic.cn/mmbiz_gif/s4IVctYyOhh8tW962ttRT7hEebnVtHIasiaEfxInFoYLkEibA04oUDPggv4BoRy57iaJ7rLr57pso1rgZD1Hj2ibdw/640?wx_fmt=gif&amp;wxfrom=5&amp;wx_lazy=1" alt="图片" style="zoom:67%;"><h2 id="aview-图片字符化" tabindex="-1">aview 图片字符化 <a class="header-anchor" href="#aview-图片字符化" aria-label="Permalink to &quot;aview 图片字符化&quot;">​</a></h2><p>这个命令可以将图片以 ASCII 码格式在终端上显示，有点 cool。安装软件包：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">apt-get install aview</span></span></code></pre></div><p>执行命令，将一张大象的图片 <strong>elephant.jpg</strong> 进行转码显示：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">asciiview elephant.jpg -driver curses</span></span></code></pre></div><h2 id="rm-rf-终结一切" tabindex="-1">rm -rf 终结一切 <a class="header-anchor" href="#rm-rf-终结一切" aria-label="Permalink to &quot;rm -rf  终结一切&quot;">​</a></h2><p>第十个 Linux 操作系统指令，已经被做成表情包，广泛流传了，废话不多说，直接上表情包……</p><p><img src="https://mmbiz.qpic.cn/mmbiz_gif/s4IVctYyOhh8tW962ttRT7hEebnVtHIan9PkE1uPnYcPnr0ZvxhZUdBRv80KfI5nicfFyn5DM3X5XmK4KD3vaOg/640?wx_fmt=gif&amp;wxfrom=5&amp;wx_lazy=1" alt="图片"></p><p>效果太过酷炫，一般人不敢看~<s>哈哈哈</s>~</p><h2 id="pv-字匀速显示" tabindex="-1">pv 字匀速显示 <a class="header-anchor" href="#pv-字匀速显示" aria-label="Permalink to &quot;pv 字匀速显示&quot;">​</a></h2><p>有时候我们在电影屏幕上看到一些字幕一个个匀速显示出来，像有人在边敲键盘，边显示一样。Linux 上的 pv 命令可实现这种效果。首先安装软件包：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sudo apt-get install pv</span></span></code></pre></div><p>这里我用英文座右铭运行实验：</p><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_gif/BFibC8wtke3u3KIlpzRpxCN8hAoicFfLSPnibgotk2iaic2YpkEtkQnGmq4GBMxLTxP0TpQOicZUib8GNA6icOzFSdB88g/640?wx_fmt=gif&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><h2 id="boxes-ascii-艺术画" tabindex="-1">boxes ASCII 艺术画 <a class="header-anchor" href="#boxes-ascii-艺术画" aria-label="Permalink to &quot;boxes ASCII 艺术画&quot;">​</a></h2><p>这个命令可以实现在输入的文本或者代码周围框上各种 ASCII 艺术画，非常有趣！首先安装软件包：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sudo apt-get install boxes</span></span></code></pre></div><p>现在我把一段文字不加任何效果输出是这样的：</p><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/BFibC8wtke3u3KIlpzRpxCN8hAoicFfLSPk1K5PEedlPibT7WCNcwCn84qLxQficwibFmReFs0UvNibgfJ2qgKWITn2w/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>现在加上小猫的图案：</p><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/BFibC8wtke3u3KIlpzRpxCN8hAoicFfLSPtVUic0U8CFLZnebjA7gicY3nKTxH3ricSqwlGEJBjIK1Uo0qhhyE6kVpg/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>亦或者小狗：</p><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/BFibC8wtke3u3KIlpzRpxCN8hAoicFfLSPrqgBxkX3HIicXxWibbFNeECW4PBPCO3ZiapficuibnOoicTQgtb04iamF4eng/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>小老鼠：</p><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/BFibC8wtke3u3KIlpzRpxCN8hAoicFfLSPGC22M364FORKHF4WPAuT2z6uQDyUHV4QMZvMVgeAHh7SibbuG8oT6lw/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>更多的效果就不展示了，等待着你们去发现~</p><h2 id="linux-logo-系统信息" tabindex="-1">linux_logo 系统信息 <a class="header-anchor" href="#linux-logo-系统信息" aria-label="Permalink to &quot;linux_logo 系统信息&quot;">​</a></h2><p>这个命令可以用来显示 linux 版本 logo 图片及系统信息。安装软件包：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sudo apt install linuxlogo</span></span></code></pre></div><p>直接运行<code>linux_logo</code>命令即可：</p><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/BFibC8wtke3u3KIlpzRpxCN8hAoicFfLSPYezCHTPKwrjOrd8r7Mp0oyjMK4JmEB4zvHTRanwxq4Tjhy6BnKog9Q/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"> 我们可以查看内置的 logo 列表：</p><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/BFibC8wtke3u3KIlpzRpxCN8hAoicFfLSPcWHhdCOjE16d5pqujejkfAyrMOjiakHKNERkWoVNyGkaxUEkm5oE5Kw/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"> 接下来我们开始利用命令在终端循环打印 logo：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">for i in {1..30};do linux_logo -f -L $i;sleep 2;done</span></span></code></pre></div><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_gif/BFibC8wtke3u3KIlpzRpxCN8hAoicFfLSPoawuWUMA3qxqAnrnRTbIxu3SpgHk2lrHusbAhyG7x6VqUx7rON5hCw/640?wx_fmt=gif&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><h2 id="screenfetch-系统、主题信息" tabindex="-1">screenfetch 系统、主题信息 <a class="header-anchor" href="#screenfetch-系统、主题信息" aria-label="Permalink to &quot;screenfetch 系统、主题信息&quot;">​</a></h2><p>这个命令可以用来显示系统、主题信息。软件包安装：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sudo apt install screenfetch</span></span></code></pre></div><p>直接运行<code>screenfetch</code>命令即可：</p><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/BFibC8wtke3u3KIlpzRpxCN8hAoicFfLSPV8XHe2eeaxn2KCZ981jS1cssCSr1ApyleA5LNFEpibdia1zqCYiakxO8Q/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><h2 id="oneko-喵星人" tabindex="-1">oneko 喵星人 <a class="header-anchor" href="#oneko-喵星人" aria-label="Permalink to &quot;oneko 喵星人&quot;">​</a></h2><p>桌面上出现一只喵星人，跟着你的鼠标跑，你不动了它就睡觉。软件包安装：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sudo apt-get install oneko</span></span></code></pre></div><p>直接<code>oneko</code>命令运行：</p><img src="https://mmbiz.qpic.cn/sz_mmbiz_gif/BFibC8wtke3u3KIlpzRpxCN8hAoicFfLSP0ptTIvibIhfibP19HWXgzlcFmUwhlCjvJp5lkRhmiaKrx9BgB8icDULfMw/640?wx_fmt=gif&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片" style="zoom:67%;"><p>要关掉这个小家伙，直接 <code>ctrl + c</code> 即可。</p><h2 id="figlet-、toilet-艺术字生成器" tabindex="-1">figlet 、toilet 艺术字生成器 <a class="header-anchor" href="#figlet-、toilet-艺术字生成器" aria-label="Permalink to &quot;figlet 、toilet 艺术字生成器&quot;">​</a></h2><p>艺术字生成器，由 ASCII 字符组成，把文本显示成标题栏。先安装软件包：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sudo apt-get install figlet</span></span>
<span class="line"><span style="color:#A6ACCD;">sudo apt-get install toilet</span></span></code></pre></div><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/BFibC8wtke3u3KIlpzRpxCN8hAoicFfLSPMe7vN1ep7voVKrwhNqohva2zOL7JibPIU1SQK1L1jwI3W8RicwbgrfyQ/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>toilet 还可以添加颜色：</p><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/BFibC8wtke3u3KIlpzRpxCN8hAoicFfLSPC4gdSp9RNAhibxf0DRzvvEicbKDycETID7q9wpWWTiakIN2kEeONYwicBQ/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><h1 id="必备命令⭐" tabindex="-1">必备命令⭐ <a class="header-anchor" href="#必备命令⭐" aria-label="Permalink to &quot;必备命令⭐&quot;">​</a></h1><p><a href="https://mp.weixin.qq.com/s?__biz=Mzk0NzI3ODMyMA==&amp;mid=2247503076&amp;idx=2&amp;sn=f74239a0c5a9653925853ca93acd9055&amp;chksm=c37bd47bf40c5d6d84350f1b4cd6b87806293bd540172b523be8ebaffcae4c2e3141a9664af1&amp;mpshare=1&amp;scene=23&amp;srcid=0412hW6Zy5Ulv5Baf5zss7Xa&amp;sharer_sharetime=1681229510633&amp;sharer_shareid=29b8a04db1dbd975e3bf4e9f47e7ac67#rd" target="_blank" rel="noreferrer">Linux 操作必备 150 个命令，速度收藏～</a></p><h2 id="线上查询及帮助" tabindex="-1">线上查询及帮助 <a class="header-anchor" href="#线上查询及帮助" aria-label="Permalink to &quot;线上查询及帮助&quot;">​</a></h2><table><thead><tr><th style="text-align:left;"><strong>man</strong></th><th style="text-align:left;">查看命令帮助，命令的词典，更复杂的还有 info，但不常用。</th></tr></thead><tbody><tr><td style="text-align:left;"><strong>help</strong></td><td style="text-align:left;">查看 Linux 内置命令的帮助，比如 cd 命令。</td></tr></tbody></table><h2 id="文件和目录操作" tabindex="-1">文件和目录操作 <a class="header-anchor" href="#文件和目录操作" aria-label="Permalink to &quot;文件和目录操作&quot;">​</a></h2><table><thead><tr><th style="text-align:left;"><strong>ls</strong></th><th style="text-align:left;">全拼 list，功能是列出目录的内容及其内容属性信息。</th></tr></thead><tbody><tr><td style="text-align:left;"><strong>cd</strong></td><td style="text-align:left;">全拼 change directory，功能是从当前工作目录切换到指定的工作目录。</td></tr><tr><td style="text-align:left;"><strong>cp</strong></td><td style="text-align:left;">全拼 copy，其功能为复制文件或目录。</td></tr><tr><td style="text-align:left;"><strong>find</strong></td><td style="text-align:left;">查找的意思，用于查找目录及目录下的文件。</td></tr><tr><td style="text-align:left;"><strong>mkdir</strong></td><td style="text-align:left;">全拼 make directories，其功能是创建目录。</td></tr><tr><td style="text-align:left;"><strong>mv</strong></td><td style="text-align:left;">全拼 move，其功能是移动或重命名文件。</td></tr><tr><td style="text-align:left;"><strong>pwd</strong></td><td style="text-align:left;">全拼 print working directory，其功能是显示当前工作目录的绝对路径。</td></tr><tr><td style="text-align:left;"><strong>rename</strong></td><td style="text-align:left;">用于重命名文件。</td></tr><tr><td style="text-align:left;"><strong>rm</strong></td><td style="text-align:left;">全拼 remove，其功能是删除一个或多个文件或目录。</td></tr><tr><td style="text-align:left;"><strong>rmdir</strong></td><td style="text-align:left;">全拼 remove empty directories，功能是删除空目录。</td></tr><tr><td style="text-align:left;"><strong>touch</strong></td><td style="text-align:left;">创建新的空文件，改变已有文件的时间戳属性。</td></tr><tr><td style="text-align:left;"><strong>tree</strong></td><td style="text-align:left;">功能是以树形结构显示目录下的内容。</td></tr><tr><td style="text-align:left;"><strong>basename</strong></td><td style="text-align:left;">显示文件名或目录名。</td></tr><tr><td style="text-align:left;"><strong>dirname</strong></td><td style="text-align:left;">显示文件或目录路径。</td></tr><tr><td style="text-align:left;"><strong>chattr</strong></td><td style="text-align:left;">改变文件的扩展属性。</td></tr><tr><td style="text-align:left;"><strong>lsattr</strong></td><td style="text-align:left;">查看文件扩展属性。</td></tr><tr><td style="text-align:left;"><strong>file</strong></td><td style="text-align:left;">显示文件的类型。</td></tr><tr><td style="text-align:left;"><strong>md5sum</strong></td><td style="text-align:left;">计算和校验文件的 MD5 值。</td></tr></tbody></table><h2 id="查看文件及内容处理" tabindex="-1">查看文件及内容处理 <a class="header-anchor" href="#查看文件及内容处理" aria-label="Permalink to &quot;查看文件及内容处理&quot;">​</a></h2><table><thead><tr><th style="text-align:left;"><strong>cat</strong></th><th style="text-align:left;">全拼 concatenate，功能是用于连接多个文件并且打印到屏幕输出或重定向到指定文件中。</th></tr></thead><tbody><tr><td style="text-align:left;"><strong>tac</strong></td><td style="text-align:left;">tac 是 cat 的反向拼写，因此命令的功能为反向显示文件内容。</td></tr><tr><td style="text-align:left;"><strong>more</strong></td><td style="text-align:left;">分页显示文件内容。</td></tr><tr><td style="text-align:left;"><strong>less</strong></td><td style="text-align:left;">分页显示文件内容，more 命令的相反用法。</td></tr><tr><td style="text-align:left;"><strong>head</strong></td><td style="text-align:left;">显示文件内容的头部。</td></tr><tr><td style="text-align:left;"><strong>tail</strong></td><td style="text-align:left;">显示文件内容的尾部。</td></tr><tr><td style="text-align:left;"><strong>cut</strong></td><td style="text-align:left;">将文件的每一行按指定分隔符分割并输出。</td></tr><tr><td style="text-align:left;"><strong>split</strong></td><td style="text-align:left;">分割文件为不同的小片段。</td></tr><tr><td style="text-align:left;"><strong>paste</strong></td><td style="text-align:left;">按行合并文件内容。</td></tr><tr><td style="text-align:left;"><strong>sort</strong></td><td style="text-align:left;">对文件的文本内容排序。</td></tr><tr><td style="text-align:left;"><strong>uniq</strong></td><td style="text-align:left;">去除重复行。oldboy</td></tr><tr><td style="text-align:left;"><strong>wc</strong></td><td style="text-align:left;">统计文件的行数、单词数或字节数。</td></tr><tr><td style="text-align:left;"><strong>iconv</strong></td><td style="text-align:left;">转换文件的编码格式。</td></tr><tr><td style="text-align:left;"><strong>dos2unix</strong></td><td style="text-align:left;">将 DOS 格式文件转换成 UNIX 格式。</td></tr><tr><td style="text-align:left;"><strong>diff</strong></td><td style="text-align:left;">全拼 difference，比较文件的差异，常用于文本文件。</td></tr><tr><td style="text-align:left;"><strong>vimdiff</strong></td><td style="text-align:left;">命令行可视化文件比较工具，常用于文本文件。</td></tr><tr><td style="text-align:left;"><strong>rev</strong></td><td style="text-align:left;">反向输出文件内容。</td></tr><tr><td style="text-align:left;"><strong>grep/egrep</strong></td><td style="text-align:left;">过滤字符串，三剑客老三。</td></tr><tr><td style="text-align:left;"><strong>join</strong></td><td style="text-align:left;">按两个文件的相同字段合并。</td></tr><tr><td style="text-align:left;"><strong>tr</strong></td><td style="text-align:left;">替换或删除字符。</td></tr><tr><td style="text-align:left;"><strong>vi/vim</strong></td><td style="text-align:left;">命令行文本编辑器。</td></tr></tbody></table><h2 id="文件压缩及解压缩" tabindex="-1">文件压缩及解压缩 <a class="header-anchor" href="#文件压缩及解压缩" aria-label="Permalink to &quot;文件压缩及解压缩&quot;">​</a></h2><table><thead><tr><th style="text-align:left;"><strong>tar</strong></th><th style="text-align:left;">打包压缩。oldboy</th></tr></thead><tbody><tr><td style="text-align:left;"><strong>unzip</strong></td><td style="text-align:left;">解压文件。</td></tr><tr><td style="text-align:left;"><strong>gzip</strong></td><td style="text-align:left;">gzip 压缩工具。</td></tr><tr><td style="text-align:left;"><strong>zip</strong></td><td style="text-align:left;">压缩工具。</td></tr></tbody></table><h2 id="信息显示" tabindex="-1">信息显示 <a class="header-anchor" href="#信息显示" aria-label="Permalink to &quot;信息显示&quot;">​</a></h2><table><thead><tr><th style="text-align:left;"><strong>uname</strong></th><th style="text-align:left;">显示操作系统相关信息的命令。</th></tr></thead><tbody><tr><td style="text-align:left;"><strong>hostname</strong></td><td style="text-align:left;">显示或者设置当前系统的主机名。</td></tr><tr><td style="text-align:left;"><strong>dmesg</strong></td><td style="text-align:left;">显示开机信息，用于诊断系统故障。</td></tr><tr><td style="text-align:left;"><strong>uptime</strong></td><td style="text-align:left;">显示系统运行时间及负载。</td></tr><tr><td style="text-align:left;"><strong>stat</strong></td><td style="text-align:left;">显示文件或文件系统的状态。</td></tr><tr><td style="text-align:left;"><strong>du</strong></td><td style="text-align:left;">计算磁盘空间使用情况。</td></tr><tr><td style="text-align:left;"><strong>df</strong></td><td style="text-align:left;">报告文件系统磁盘空间的使用情况。</td></tr><tr><td style="text-align:left;"><strong>top</strong></td><td style="text-align:left;">实时显示系统资源使用情况。</td></tr><tr><td style="text-align:left;"><strong>free</strong></td><td style="text-align:left;">查看系统内存。</td></tr><tr><td style="text-align:left;"><strong>date</strong></td><td style="text-align:left;">显示与设置系统时间。</td></tr><tr><td style="text-align:left;"><strong>cal</strong></td><td style="text-align:left;">查看日历等时间信息。</td></tr></tbody></table><h2 id="搜索文件" tabindex="-1">搜索文件 <a class="header-anchor" href="#搜索文件" aria-label="Permalink to &quot;搜索文件&quot;">​</a></h2><table><thead><tr><th style="text-align:left;"><strong>which</strong></th><th style="text-align:left;">查找二进制命令，按环境变量 PATH 路径查找。</th></tr></thead><tbody><tr><td style="text-align:left;"><strong>find</strong></td><td style="text-align:left;">从磁盘遍历查找文件或目录。</td></tr><tr><td style="text-align:left;"><strong>whereis</strong></td><td style="text-align:left;">查找二进制命令，按环境变量 PATH 路径查找。</td></tr><tr><td style="text-align:left;"><strong>locate</strong></td><td style="text-align:left;">从数据库 (/var/lib/mlocate/mlocate.db) 查找命令，使用 updatedb 更新库。</td></tr></tbody></table><h2 id="用户管理" tabindex="-1">用户管理 <a class="header-anchor" href="#用户管理" aria-label="Permalink to &quot;用户管理&quot;">​</a></h2><table><thead><tr><th style="text-align:left;"><strong>useradd</strong></th><th style="text-align:left;">添加用户。</th></tr></thead><tbody><tr><td style="text-align:left;"><strong>usermod</strong></td><td style="text-align:left;">修改系统已经存在的用户属性。</td></tr><tr><td style="text-align:left;"><strong>userdel</strong></td><td style="text-align:left;">删除用户。</td></tr><tr><td style="text-align:left;"><strong>groupadd</strong></td><td style="text-align:left;">添加用户组。</td></tr><tr><td style="text-align:left;"><strong>passwd</strong></td><td style="text-align:left;">修改用户密码。</td></tr><tr><td style="text-align:left;"><strong>chage</strong></td><td style="text-align:left;">修改用户密码有效期限。</td></tr><tr><td style="text-align:left;"><strong>id</strong></td><td style="text-align:left;">查看用户的 uid,gid 及归属的用户组。</td></tr><tr><td style="text-align:left;"><strong>su</strong></td><td style="text-align:left;">切换用户身份。</td></tr><tr><td style="text-align:left;"><strong>visudo</strong></td><td style="text-align:left;">编辑 / etc/sudoers 文件的专属命令。</td></tr><tr><td style="text-align:left;"><strong>sudo</strong></td><td style="text-align:left;">以另外一个用户身份（默认 root 用户）执行事先在 sudoers 文件允许的命令。</td></tr></tbody></table><h2 id="基础网络操作" tabindex="-1">基础网络操作 <a class="header-anchor" href="#基础网络操作" aria-label="Permalink to &quot;基础网络操作&quot;">​</a></h2><table><thead><tr><th style="text-align:left;"><strong>telnet</strong></th><th style="text-align:left;">使用 TELNET 协议远程登录。</th></tr></thead><tbody><tr><td style="text-align:left;"><strong>ssh</strong></td><td style="text-align:left;">使用 SSH 加密协议远程登录。</td></tr><tr><td style="text-align:left;"><strong>scp</strong></td><td style="text-align:left;">全拼 secure copy，用于不同主机之间复制文件。</td></tr><tr><td style="text-align:left;"><strong>wget</strong></td><td style="text-align:left;">命令行下载文件。</td></tr><tr><td style="text-align:left;"><strong>ping</strong></td><td style="text-align:left;">测试主机之间网络的连通性。</td></tr><tr><td style="text-align:left;"><strong>route</strong></td><td style="text-align:left;">显示和设置 linux 系统的路由表。</td></tr><tr><td style="text-align:left;"><strong>ifconfig</strong></td><td style="text-align:left;">查看、配置、启用或禁用网络接口的命令。</td></tr><tr><td style="text-align:left;"><strong>ifup</strong></td><td style="text-align:left;">启动网卡。</td></tr><tr><td style="text-align:left;"><strong>ifdown</strong></td><td style="text-align:left;">关闭网卡。</td></tr><tr><td style="text-align:left;"><strong>netstat</strong></td><td style="text-align:left;">查看网络状态。</td></tr><tr><td style="text-align:left;"><strong>ss</strong></td><td style="text-align:left;">查看网络状态。</td></tr></tbody></table><h2 id="深入网络操作" tabindex="-1">深入网络操作 <a class="header-anchor" href="#深入网络操作" aria-label="Permalink to &quot;深入网络操作&quot;">​</a></h2><table><thead><tr><th style="text-align:left;"><strong>nmap</strong></th><th style="text-align:left;">网络扫描命令。</th></tr></thead><tbody><tr><td style="text-align:left;"><strong>lsof</strong></td><td style="text-align:left;">全名 list open files，也就是列举系统中已经被打开的文件。</td></tr><tr><td style="text-align:left;"><strong>mail</strong></td><td style="text-align:left;">发送和接收邮件。</td></tr><tr><td style="text-align:left;"><strong>mutt</strong></td><td style="text-align:left;">邮件管理命令。</td></tr><tr><td style="text-align:left;"><strong>nslookup</strong></td><td style="text-align:left;">交互式查询互联网 DNS 服务器的命令。</td></tr><tr><td style="text-align:left;"><strong>dig</strong></td><td style="text-align:left;">查找 DNS 解析过程。</td></tr><tr><td style="text-align:left;"><strong>host</strong></td><td style="text-align:left;">查询 DNS 的命令。</td></tr><tr><td style="text-align:left;"><strong>traceroute</strong></td><td style="text-align:left;">追踪数据传输路由状况。</td></tr><tr><td style="text-align:left;"><strong>tcpdump</strong></td><td style="text-align:left;">命令行的抓包工具。</td></tr></tbody></table><h2 id="磁盘与文件系统" tabindex="-1">磁盘与文件系统 <a class="header-anchor" href="#磁盘与文件系统" aria-label="Permalink to &quot;磁盘与文件系统&quot;">​</a></h2><table><thead><tr><th style="text-align:left;"><strong>mount</strong></th><th style="text-align:left;">挂载文件系统。</th></tr></thead><tbody><tr><td style="text-align:left;"><strong>umount</strong></td><td style="text-align:left;">卸载文件系统。</td></tr><tr><td style="text-align:left;"><strong>fsck</strong></td><td style="text-align:left;">检查并修复 Linux 文件系统。</td></tr><tr><td style="text-align:left;"><strong>dd</strong></td><td style="text-align:left;">转换或复制文件。</td></tr><tr><td style="text-align:left;"><strong>dumpe2fs</strong></td><td style="text-align:left;">导出 ext2/ext3/ext4 文件系统信息。</td></tr><tr><td style="text-align:left;"><strong>dump</strong></td><td style="text-align:left;">ext2/3/4 文件系统备份工具。</td></tr><tr><td style="text-align:left;"><strong>fdisk</strong></td><td style="text-align:left;">磁盘分区命令，适用于 2TB 以下磁盘分区。</td></tr><tr><td style="text-align:left;"><strong>parted</strong></td><td style="text-align:left;">磁盘分区命令，没有磁盘大小限制，常用于 2TB 以下磁盘分区。</td></tr><tr><td style="text-align:left;"><strong>mkfs</strong></td><td style="text-align:left;">格式化创建 Linux 文件系统。</td></tr><tr><td style="text-align:left;"><strong>partprobe</strong></td><td style="text-align:left;">更新内核的硬盘分区表信息。</td></tr><tr><td style="text-align:left;"><strong>e2fsck</strong></td><td style="text-align:left;">检查 ext2/ext3/ext4 类型文件系统。</td></tr><tr><td style="text-align:left;"><strong>mkswap</strong></td><td style="text-align:left;">创建 Linux 交换分区。</td></tr><tr><td style="text-align:left;"><strong>swapon</strong></td><td style="text-align:left;">启用交换分区。</td></tr><tr><td style="text-align:left;"><strong>swapoff</strong></td><td style="text-align:left;">关闭交换分区。</td></tr><tr><td style="text-align:left;"><strong>sync</strong></td><td style="text-align:left;">将内存缓冲区内的数据写入磁盘。</td></tr><tr><td style="text-align:left;"><strong>resize2fs</strong></td><td style="text-align:left;">调整 ext2/ext3/ext4 文件系统大小。</td></tr></tbody></table><h2 id="系统权限及用户授权" tabindex="-1">系统权限及用户授权 <a class="header-anchor" href="#系统权限及用户授权" aria-label="Permalink to &quot;系统权限及用户授权&quot;">​</a></h2><table><thead><tr><th style="text-align:left;"><strong>chmod</strong></th><th style="text-align:left;">改变文件或目录权限。</th></tr></thead><tbody><tr><td style="text-align:left;"><strong>chown</strong></td><td style="text-align:left;">改变文件或目录的属主和属组。</td></tr><tr><td style="text-align:left;"><strong>chgrp</strong></td><td style="text-align:left;">更改文件用户组。</td></tr><tr><td style="text-align:left;"><strong>umask</strong></td><td style="text-align:left;">显示或设置权限掩码。</td></tr></tbody></table><h2 id="查看系统用户登陆信息" tabindex="-1">查看系统用户登陆信息 <a class="header-anchor" href="#查看系统用户登陆信息" aria-label="Permalink to &quot;查看系统用户登陆信息&quot;">​</a></h2><table><thead><tr><th style="text-align:left;"><strong>whoami</strong></th><th style="text-align:left;">显示当前有效的用户名称，相当于执行 id -un 命令。</th></tr></thead><tbody><tr><td style="text-align:left;"><strong>who</strong></td><td style="text-align:left;">显示目前登录系统的用户信息。</td></tr><tr><td style="text-align:left;"><strong>w</strong></td><td style="text-align:left;">显示已经登陆系统的用户列表，并显示用户正在执行的指令。</td></tr><tr><td style="text-align:left;"><strong>last</strong></td><td style="text-align:left;">显示登入系统的用户。</td></tr><tr><td style="text-align:left;"><strong>lastlog</strong></td><td style="text-align:left;">显示系统中所有用户最近一次登录信息。</td></tr><tr><td style="text-align:left;"><strong>users</strong></td><td style="text-align:left;">显示当前登录系统的所有用户的用户列表。</td></tr><tr><td style="text-align:left;"><strong>finger</strong></td><td style="text-align:left;">查找并显示用户信息。</td></tr></tbody></table><h2 id="内置命令及其它" tabindex="-1">内置命令及其它 <a class="header-anchor" href="#内置命令及其它" aria-label="Permalink to &quot;内置命令及其它&quot;">​</a></h2><table><thead><tr><th style="text-align:left;"><strong>echo</strong></th><th style="text-align:left;">打印变量，或直接输出指定的字符串</th></tr></thead><tbody><tr><td style="text-align:left;"><strong>printf</strong></td><td style="text-align:left;">将结果格式化输出到标准输出。</td></tr><tr><td style="text-align:left;"><strong>rpm</strong></td><td style="text-align:left;">管理 rpm 包的命令。</td></tr><tr><td style="text-align:left;"><strong>yum</strong></td><td style="text-align:left;">自动化简单化地管理 rpm 包的命令。</td></tr><tr><td style="text-align:left;"><strong>watch</strong></td><td style="text-align:left;">周期性的执行给定的命令，并将命令的输出以全屏方式显示。</td></tr><tr><td style="text-align:left;"><strong>alias</strong></td><td style="text-align:left;">设置系统别名。</td></tr><tr><td style="text-align:left;"><strong>unalias</strong></td><td style="text-align:left;">取消系统别名。</td></tr><tr><td style="text-align:left;"><strong>date</strong></td><td style="text-align:left;">查看或设置系统时间。</td></tr><tr><td style="text-align:left;"><strong>clear</strong></td><td style="text-align:left;">清除屏幕，简称清屏。</td></tr><tr><td style="text-align:left;"><strong>history</strong></td><td style="text-align:left;">查看命令执行的历史纪录。</td></tr><tr><td style="text-align:left;"><strong>eject</strong></td><td style="text-align:left;">弹出光驱。</td></tr><tr><td style="text-align:left;"><strong>time</strong></td><td style="text-align:left;">计算命令执行时间。</td></tr><tr><td style="text-align:left;"><strong>nc</strong></td><td style="text-align:left;">功能强大的网络工具。</td></tr><tr><td style="text-align:left;"><strong>xargs</strong></td><td style="text-align:left;">将标准输入转换成命令行参数。</td></tr><tr><td style="text-align:left;"><strong>exec</strong></td><td style="text-align:left;">调用并执行指令的命令。</td></tr><tr><td style="text-align:left;"><strong>export</strong></td><td style="text-align:left;">设置或者显示环境变量。</td></tr><tr><td style="text-align:left;"><strong>unset</strong></td><td style="text-align:left;">删除变量或函数。</td></tr><tr><td style="text-align:left;"><strong>type</strong></td><td style="text-align:left;">用于判断另外一个命令是否是内置命令。</td></tr><tr><td style="text-align:left;"><strong>bc</strong></td><td style="text-align:left;">命令行科学计算器</td></tr></tbody></table><h2 id="系统管理与性能监视" tabindex="-1">系统管理与性能监视 <a class="header-anchor" href="#系统管理与性能监视" aria-label="Permalink to &quot;系统管理与性能监视&quot;">​</a></h2><table><thead><tr><th style="text-align:left;"><strong>chkconfig</strong></th><th style="text-align:left;">管理 Linux 系统开机启动项。</th></tr></thead><tbody><tr><td style="text-align:left;"><strong>vmstat</strong></td><td style="text-align:left;">虚拟内存统计。</td></tr><tr><td style="text-align:left;"><strong>mpstat</strong></td><td style="text-align:left;">显示各个可用 CPU 的状态统计。</td></tr><tr><td style="text-align:left;"><strong>iostat</strong></td><td style="text-align:left;">统计系统 IO。</td></tr><tr><td style="text-align:left;"><strong>sar</strong></td><td style="text-align:left;">全面地获取系统的 CPU、运行队列、磁盘 I/O、分页（交换区）、内存、 CPU 中断和网络等性能数据。</td></tr><tr><td style="text-align:left;"><strong>ipcs</strong></td><td style="text-align:left;">用于报告 Linux 中进程间通信设施的状态，显示的信息包括消息列表、共享内存和信号量的信息。</td></tr><tr><td style="text-align:left;"><strong>ipcrm</strong></td><td style="text-align:left;">用来删除一个或更多的消息队列、信号量集或者共享内存标识。</td></tr><tr><td style="text-align:left;"><strong>strace</strong></td><td style="text-align:left;">用于诊断、调试 Linux 用户空间跟踪器。我们用它来监控用户空间进程和内核的交互，比如系统调用、信号传递、进程状态变更等。</td></tr><tr><td style="text-align:left;"><strong>ltrace</strong></td><td style="text-align:left;">命令会跟踪进程的库函数调用, 它会显现出哪个库函数被调用。</td></tr></tbody></table><h2 id="关机-重启-注销和查看信息" tabindex="-1">关机 / 重启 / 注销和查看信息 <a class="header-anchor" href="#关机-重启-注销和查看信息" aria-label="Permalink to &quot;关机 / 重启 / 注销和查看信息&quot;">​</a></h2><table><thead><tr><th style="text-align:left;"><strong>shutdown</strong></th><th style="text-align:left;">关机。</th></tr></thead><tbody><tr><td style="text-align:left;"><strong>halt</strong></td><td style="text-align:left;">关机。</td></tr><tr><td style="text-align:left;"><strong>poweroff</strong></td><td style="text-align:left;">关闭电源。</td></tr><tr><td style="text-align:left;"><strong>logout</strong></td><td style="text-align:left;">退出当前登录的 Shell。</td></tr><tr><td style="text-align:left;"><strong>exit</strong></td><td style="text-align:left;">退出当前登录的 Shell。</td></tr><tr><td style="text-align:left;"><strong>Ctrl+d</strong></td><td style="text-align:left;">退出当前登录的 Shell 的快捷键。</td></tr></tbody></table><h2 id="进程管理" tabindex="-1">进程管理 <a class="header-anchor" href="#进程管理" aria-label="Permalink to &quot;进程管理&quot;">​</a></h2><table><thead><tr><th style="text-align:left;"><strong>bg</strong></th><th style="text-align:left;">将一个在后台暂停的命令，变成继续执行 （在后台执行）。</th></tr></thead><tbody><tr><td style="text-align:left;"><strong>fg</strong></td><td style="text-align:left;">将后台中的命令调至前台继续运行。</td></tr><tr><td style="text-align:left;"><strong>jobs</strong></td><td style="text-align:left;">查看当前有多少在后台运行的命令。</td></tr><tr><td style="text-align:left;"><strong>kill</strong></td><td style="text-align:left;">终止进程。</td></tr><tr><td style="text-align:left;"><strong>killall</strong></td><td style="text-align:left;">通过进程名终止进程。</td></tr><tr><td style="text-align:left;"><strong>pkill</strong></td><td style="text-align:left;">通过进程名终止进程。</td></tr><tr><td style="text-align:left;"><strong>crontab</strong></td><td style="text-align:left;">定时任务命令。</td></tr><tr><td style="text-align:left;"><strong>ps</strong></td><td style="text-align:left;">显示进程的快照。</td></tr><tr><td style="text-align:left;"><strong>pstree</strong></td><td style="text-align:left;">树形显示进程。</td></tr><tr><td style="text-align:left;"><strong>nice/renice</strong></td><td style="text-align:left;">调整程序运行的优先级。</td></tr><tr><td style="text-align:left;"><strong>nohup</strong></td><td style="text-align:left;">忽略挂起信号运行指定的命令。</td></tr><tr><td style="text-align:left;"><strong>pgrep</strong></td><td style="text-align:left;">查找匹配条件的进程。</td></tr><tr><td style="text-align:left;"><strong>runlevel</strong></td><td style="text-align:left;">查看系统当前运行级别。</td></tr><tr><td style="text-align:left;"><strong>init</strong></td><td style="text-align:left;">切换运行级别。</td></tr><tr><td style="text-align:left;"><strong>service</strong></td><td style="text-align:left;">启动、停止、重新启动和关闭系统服务，还可以显示所有系统服务的当前状态。</td></tr></tbody></table><h1 id="后台运行任务" tabindex="-1">后台运行任务 <a class="header-anchor" href="#后台运行任务" aria-label="Permalink to &quot;后台运行任务&quot;">​</a></h1><h2 id="问题的引入" tabindex="-1">问题的引入 <a class="header-anchor" href="#问题的引入" aria-label="Permalink to &quot;问题的引入&quot;">​</a></h2><blockquote><p>程序员最不能容忍的是在使用终端的时候往往因为网络，关闭屏幕，执行CTRL+C等原因造成ssh断开造成正在运行程序退出，使得我们的工作功亏一篑。</p></blockquote><blockquote><p>其背后的主要原因在于上述的相关操作，shell默认会发送中断信号给该终端session关联的进程，从而导致进程跟随终端退出，为了弄清这个问题我们首先要了解两种中断信号：</p></blockquote><blockquote><p>1）sigint：signal interrupt，ctrl+c会发送此信号，主动关闭程序</p><p>2）sighup: signal hang up，关闭终端，网络断线，关闭屏幕会发送此挂断信号。</p></blockquote><p>今天就给大家介绍linux中几种后台任务的执行方法避免上述问题。</p><h2 id="符号" tabindex="-1">&amp; 符号 <a class="header-anchor" href="#符号" aria-label="Permalink to &quot;&amp; 符号&quot;">​</a></h2><blockquote><p>这是一种把 &amp;放在执行命令最后，使启动的程序忽略sigint信号,此时执行ctrl+c关闭就不会关闭此进程，但是当屏幕关闭，断网仍然会造成进程退出。</p></blockquote><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sh test.sh &amp;</span></span></code></pre></div><h2 id="nohup指令" tabindex="-1">nohup指令 <a class="header-anchor" href="#nohup指令" aria-label="Permalink to &quot;nohup指令&quot;">​</a></h2><blockquote><p>nohup（no hang up）,意思就是不挂断运行，用nohup运行命令可以使命令永久执行下去，和用户终端没有关系，断开SSH不影响运行，nohup捕获了SIGHUP，并做了忽略处理，因此当屏幕关闭，断网等造成ssh中断时进程不会退出。但是ctrl+c可以关闭关闭该进程。因此大多数情况同时使用nohup和&amp;启动的程序，ctrl+c和关闭终端都无法关闭。在缺省情况下所有输出都被重定向到一个名为nohup.out的文件</p></blockquote><p>nohup指令基本使用格式：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">nohup Command \[ Arg ... \] \[ &amp; \]</span></span></code></pre></div><p>后台不中断执行./test.sh,stdout输出给out.log，stderr输出给err.log</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">nohup ./test.sh &gt; out.log 2&gt;err.log  &amp;</span></span></code></pre></div><p>相关的数字含义如下：</p><ul><li>0 – stdin (standard input)，</li><li>1 – stdout (standard output),显然 nohup command &gt; out.log 等价于 nohup command 1&gt; out.log</li><li>2 – stderr (standard error)</li></ul><p>可能你也会见到这种写法，其含义是把stderr也重定向给stdin</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">nohup ./test.sh &gt; out.log 2&gt;&amp;1  &amp;</span></span></code></pre></div><h2 id="ctrl-z、jobs、fg、bg" tabindex="-1">ctrl + z、jobs、fg、bg <a class="header-anchor" href="#ctrl-z、jobs、fg、bg" aria-label="Permalink to &quot;ctrl + z、jobs、fg、bg&quot;">​</a></h2><blockquote><p>如果我们程序在启动的时候并没有使用&amp;，nohup怎么办呢，难道我们需要先执行ctrl + c将在前台执行的进程终止执行再重新启动吗，显然有好的方法！</p></blockquote><h3 id="ctrl-z" tabindex="-1">ctrl + z <a class="header-anchor" href="#ctrl-z" aria-label="Permalink to &quot;ctrl + z&quot;">​</a></h3><p>将一个正在前台执行的作业进程放到后台，并且暂停，用术语讲就是挂起,执行后如下：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">[1]+ Stopped ./test.sh</span></span></code></pre></div><h3 id="jobs" tabindex="-1">jobs <a class="header-anchor" href="#jobs" aria-label="Permalink to &quot;jobs&quot;">​</a></h3><p>查看当前有多少在后台运行的命令,[jobnumber] 就是作业号。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">jobs  </span></span>
<span class="line"><span style="color:#A6ACCD;">[1]+ Stopped ./test.sh   </span></span>
<span class="line"><span style="color:#A6ACCD;">[2]+ Running ./test2.sh &amp;</span></span></code></pre></div><h3 id="bg" tabindex="-1">bg <a class="header-anchor" href="#bg" aria-label="Permalink to &quot;bg&quot;">​</a></h3><p>将后台中暂停（挂起）的作业进程继续运行,例如把1号作业(./test.sh) 放到后台运行，注意看已经带了&amp;</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">bg 1  </span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">[1]+ ./test.sh  &amp;</span></span></code></pre></div><h3 id="fg" tabindex="-1">fg <a class="header-anchor" href="#fg" aria-label="Permalink to &quot;fg&quot;">​</a></h3><p>将后台中的作业进程调至前台继续运行,例如把2号作业（./test2.sh &amp;）调至前台运行</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">fg 2   </span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">./test2.sh</span></span></code></pre></div><h2 id="screen命令" tabindex="-1">screen命令 <a class="header-anchor" href="#screen命令" aria-label="Permalink to &quot;screen命令&quot;">​</a></h2><h3 id="介绍" tabindex="-1">介绍 <a class="header-anchor" href="#介绍" aria-label="Permalink to &quot;介绍&quot;">​</a></h3><blockquote><p>如果说上面的方法是通过linux 相关本身命令实现了前后台任务调度，那么screen就提供了另外一种思路。</p></blockquote><blockquote><p>不说人话的版本：GNU Screen是一款由GNU计划开发的用于命令行终端切换的自由软件。用户可以通过该软件同时连接多个本地或远程的命令行会话，并在其间自由切换。GNU Screen可以看作是窗口管理器的命令行界面版本。它提供了统一的管理多个会话的界面和相应的功能。</p></blockquote><blockquote><p>说人话的版本: 我们可以粗略地认为screen是一个虚拟终端软件，直接在linux系统里面启动了另外一个后台程序接管（维持）了你的终端会话，当你直接连接的终端ssh断开时他仍然让程序认为你的ssh持续链接着，这样也就不会出现进程接收到中断信号而退出。</p></blockquote><h3 id="安装" tabindex="-1">安装 <a class="header-anchor" href="#安装" aria-label="Permalink to &quot;安装&quot;">​</a></h3><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">yum install screen</span></span></code></pre></div><h3 id="使用" tabindex="-1">使用 <a class="header-anchor" href="#使用" aria-label="Permalink to &quot;使用&quot;">​</a></h3><p>1）新建会话</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">screen -S yourname -&gt; 新建一个叫yourname的session</span></span></code></pre></div><p>2） 列出当前所有的session</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">screen -ls</span></span></code></pre></div><p>3）恢复会话（回到yourname这个session）</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">screen -r yourname</span></span></code></pre></div><p>4） detach某个session</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">screen -d yourname -&gt; 远程detach某个session </span></span>
<span class="line"><span style="color:#A6ACCD;">screen -d -r yourname -&gt; 结束当前session并回到yourname这个session</span></span></code></pre></div><p>5）删除会话</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">screen -S pid-X quit</span></span></code></pre></div><h1 id="别再用kill-9关闭程序了" tabindex="-1">别再用kill -9关闭程序了 <a class="header-anchor" href="#别再用kill-9关闭程序了" aria-label="Permalink to &quot;别再用kill -9关闭程序了&quot;">​</a></h1><blockquote><p>“</p><p>kill 可将指定的信息送至程序。预设的信息为 SIGTERM(15)，可将指定程序终止。若仍无法终止该程序，可使用 SIGKILL(9) 信息尝试强制删除程序。程序或工作的编号可利用 ps 指令或 jobs 指令查看。</p></blockquote><h3 id="kill-9-pid" tabindex="-1">kill -9 pid ??? <a class="header-anchor" href="#kill-9-pid" aria-label="Permalink to &quot;kill -9 pid ???&quot;">​</a></h3><p>讲的这个复杂，简单点来说就是用来杀死 Linux 中的进程，啥？你问我啥是进程？请自行百度。</p><p>我相信很多人都用过 kill -9 pid 这个命令，彻底杀死进程的意思，一般情况我们使用它没有上面问题，但是在我们项目中使用它就有可能存在致命的问题。</p><h3 id="kill-9-pid-带来的问题" tabindex="-1">kill -9 pid 带来的问题 <a class="header-anchor" href="#kill-9-pid-带来的问题" aria-label="Permalink to &quot;kill -9 pid 带来的问题&quot;">​</a></h3><p>由于kill -9 属于暴力删除，所以会给程序带来比较严重的后果，那究竟会带来什么后果呢？</p><p>举个栗子：转账功能，再给两个账户进行加钱扣钱的时候突然断电了？这个时候会发生什么事情？</p><p>对于 InnoDB 存储引擎来说，没有什么损失，因为它支持事务，但是对于 MyISAM 引擎来说那简直就是灾难，为什么？</p><p>假如给 A 账户扣了钱，现在需要将 B 账户加钱，这个时候停电了，就会造成，A 的钱被扣了，但是 B 没有拿到这笔钱，这在生产环境是绝对不允许的，kill -9 相当于突然断电的效果。</p><p>当然了，像转账这种，肯定不是使用 MyISAM 引擎，但是如今分布式火了起来，跨服务转账已经是很平常的事情。</p><p>这种时候如果使用 kill -9 去停止服务，那就不是你的事务能保证数据的准确性了，这个时候你可能会想到分布式事务。</p><p>这个世界上没有绝对的安全系统或者架构，分布式事务也是一样，他也会存在问题，概率很小。</p><p>如果一旦发生，损失有可能是无法弥补的，所以一定不能使用 kill -9 去停止服务，因为你不知道他会造成什么后果。</p><p>在 MyISAM 引擎中表现的更明显，比如用户的信息由两张表维护，管理员修改用户信息的时候需要修改两张表。</p><p>但由于你的 kill -9 暴力结束项目，导致只修改成功了一张表，这也会导致数据的不一致性。</p><p>这是小事，因为大不了再修改一次，但是金钱、合同这些重要的信息如果由于你的暴力删除导致错乱，我觉得可能比删库跑路还严重，至少删库还能恢复，你这个都不知道错在哪里。</p><p>那我们应该怎么结束项目呢？其实 Java 给我们提供了结束项目的功能，比如：Tomcat 可以使用 shutdown.bat/shutdown.sh 进行优雅结束。</p><p>什么叫优雅结束？</p><ul><li>第一步：停止接收请求和内部线程。</li><li>第二步：判断是否有线程正在执行。</li><li>第三步：等待正在执行的线程执行完毕。</li><li>第四步：停止容器。</li></ul><p>以上四步才是正常的结束流程，那 SpringBoot 怎么正常结束服务呢？下面我介绍几种正常结束服务的方案，请拿好小本本做好笔记。</p><h3 id="优雅结束服务" tabindex="-1">优雅结束服务 <a class="header-anchor" href="#优雅结束服务" aria-label="Permalink to &quot;优雅结束服务&quot;">​</a></h3><h3 id="_1kill-15-pid" tabindex="-1">①kill -15 pid <a class="header-anchor" href="#_1kill-15-pid" aria-label="Permalink to &quot;①kill -15 pid&quot;">​</a></h3><p>这种方式也会比较优雅的结束进程（项目），使用他的时候需要慎重，为什么呢？</p><p>我们来看个例子，我写了一个普通的 controller 方法做测试：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">@GetMapping(value = &quot;/test&quot;)</span></span>
<span class="line"><span style="color:#A6ACCD;">    public String test(){</span></span>
<span class="line"><span style="color:#A6ACCD;">        log.info(&quot;test --- start&quot;);</span></span>
<span class="line"><span style="color:#A6ACCD;">        try {</span></span>
<span class="line"><span style="color:#A6ACCD;">            Thread.sleep(100000);</span></span>
<span class="line"><span style="color:#A6ACCD;">        } catch (InterruptedException e) {</span></span>
<span class="line"><span style="color:#A6ACCD;">            e.printStackTrace();</span></span>
<span class="line"><span style="color:#A6ACCD;">        }</span></span>
<span class="line"><span style="color:#A6ACCD;">        log.info(&quot;test --- end&quot;);</span></span>
<span class="line"><span style="color:#A6ACCD;">        return &quot;test&quot;;</span></span>
<span class="line"><span style="color:#A6ACCD;">    }</span></span></code></pre></div><p>代码很简单，打印：test — start 之后让让程序休眠 100 秒，然后再打印：test — end。</p><p>在线程休眠中我们使用 kill -15 pid 来结束这个进程，你们猜 test — end 会被打印吗？</p><p>application.yml：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">server:  port: 9988</span></span></code></pre></div><p>启动项目：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sudo mvn spring-boot:run</span></span></code></pre></div><p>这是 maven 启动 SpringBoot 项目的方式：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/QFzRdz9libEaO7cicciaPtp3yI5mTqpl2TAn0iamSNcJvcJJmAeLqhnGicibaSUVm4ussicwK1KvicicXzJpQQwU4TsL3MQ/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>看到这个就代表项目启动成了，找到项目的进程 id：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sudo ps -ef |grep shutdown</span></span></code></pre></div><p><img src="https://mmbiz.qpic.cn/mmbiz_png/QFzRdz9libEaO7cicciaPtp3yI5mTqpl2TA1GZJDzzsuR6oeVS3s9OftGIeScsHRWibOnJjgBxFF4rYUWhWVxTOJMw/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>这个就是项目的进程号，接下来我们先测试 test 接口，让线程进入休眠状态，然后再使用 kill -15 14086 停止项目：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sudo curl 127.0.0.1:9988/test</span></span></code></pre></div><p>回到项目日志：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/QFzRdz9libEaO7cicciaPtp3yI5mTqpl2TAoXLic4J3QdU1VYpInBudPlNwtCDLckGIRiaJMZbLKkySzHhacbucFb7g/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>我们发现请求已经到达服务，并且线程已经成功进入休眠，现在我们 kill -15 14086 结束进程：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sudo kill -15 14086</span></span></code></pre></div><p>这就和 sleep 这个方法有关了，在线程休眠期间，当调用线程的 interrupt 方法的时候会导致 sleep 抛出异常。</p><p>这里很明显就是 kill -15 这个命令会让程序马上调用线程的 interrupt 方法，目的是为了让线程停止。</p><p>虽然让线程停止，但线程什么时候停止还是线程自己说的算，这就是为什么我们还能看到：test — end 的原因。</p><h3 id="_2configurableapplicationcontext-colse" tabindex="-1">②ConfigurableApplicationContext colse <a class="header-anchor" href="#_2configurableapplicationcontext-colse" aria-label="Permalink to &quot;②ConfigurableApplicationContext colse&quot;">​</a></h3><p>我们先看怎么实现：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">package com.ymy.controller;</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">import lombok.extern.slf4j.Slf4j;</span></span>
<span class="line"><span style="color:#A6ACCD;">import org.springframework.beans.BeansException;</span></span>
<span class="line"><span style="color:#A6ACCD;">import org.springframework.context.ApplicationContext;</span></span>
<span class="line"><span style="color:#A6ACCD;">import org.springframework.context.ApplicationContextAware;</span></span>
<span class="line"><span style="color:#A6ACCD;">import org.springframework.context.ConfigurableApplicationContext;</span></span>
<span class="line"><span style="color:#A6ACCD;">import org.springframework.web.bind.annotation.GetMapping;</span></span>
<span class="line"><span style="color:#A6ACCD;">import org.springframework.web.bind.annotation.PostMapping;</span></span>
<span class="line"><span style="color:#A6ACCD;">import org.springframework.web.bind.annotation.RestController;</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">@RestController</span></span>
<span class="line"><span style="color:#A6ACCD;">@Slf4j</span></span>
<span class="line"><span style="color:#A6ACCD;">public class TestController  implements ApplicationContextAware {</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">    private  ApplicationContext  context;</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">    @Override</span></span>
<span class="line"><span style="color:#A6ACCD;">    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {</span></span>
<span class="line"><span style="color:#A6ACCD;">        this.context = applicationContext;</span></span>
<span class="line"><span style="color:#A6ACCD;">    }</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">    @GetMapping(value = &quot;/test&quot;)</span></span>
<span class="line"><span style="color:#A6ACCD;">    public String test(){</span></span>
<span class="line"><span style="color:#A6ACCD;">        log.info(&quot;test --- start&quot;);</span></span>
<span class="line"><span style="color:#A6ACCD;">        try {</span></span>
<span class="line"><span style="color:#A6ACCD;">            Thread.sleep(100000);</span></span>
<span class="line"><span style="color:#A6ACCD;">        } catch (InterruptedException e) {</span></span>
<span class="line"><span style="color:#A6ACCD;">            e.printStackTrace();</span></span>
<span class="line"><span style="color:#A6ACCD;">        }</span></span>
<span class="line"><span style="color:#A6ACCD;">        log.info(&quot;test --- end&quot;);</span></span>
<span class="line"><span style="color:#A6ACCD;">        return &quot;test&quot;;</span></span>
<span class="line"><span style="color:#A6ACCD;">    }</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">    /**</span></span>
<span class="line"><span style="color:#A6ACCD;">     * 停机</span></span>
<span class="line"><span style="color:#A6ACCD;">     */</span></span>
<span class="line"><span style="color:#A6ACCD;">    @PostMapping(value = &quot;shutdown&quot;)</span></span>
<span class="line"><span style="color:#A6ACCD;">    public void shutdown(){</span></span>
<span class="line"><span style="color:#A6ACCD;">        ConfigurableApplicationContext cyx = (ConfigurableApplicationContext) context;</span></span>
<span class="line"><span style="color:#A6ACCD;">        cyx.close();</span></span>
<span class="line"><span style="color:#A6ACCD;">    }</span></span>
<span class="line"><span style="color:#A6ACCD;">}</span></span></code></pre></div><p>重点在：cyx.close(); 为什么他能停止 SpringBoot 项目呢？请看源码：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">public void close() {</span></span>
<span class="line"><span style="color:#A6ACCD;">        synchronized(this.startupShutdownMonitor) {</span></span>
<span class="line"><span style="color:#A6ACCD;">            this.doClose();</span></span>
<span class="line"><span style="color:#A6ACCD;">            if (this.shutdownHook != null) {</span></span>
<span class="line"><span style="color:#A6ACCD;">                try {</span></span>
<span class="line"><span style="color:#A6ACCD;">                    Runtime.getRuntime().removeShutdownHook(this.shutdownHook);</span></span>
<span class="line"><span style="color:#A6ACCD;">                } catch (IllegalStateException var4) {</span></span>
<span class="line"><span style="color:#A6ACCD;">                }</span></span>
<span class="line"><span style="color:#A6ACCD;">            }</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">        }</span></span>
<span class="line"><span style="color:#A6ACCD;">    }</span></span></code></pre></div><p>程序在启动的时候向 JVM 注册了一个关闭钩子，我们在执行 colse 方法的时候会删除这个关闭钩子，JVM 就会知道这是需要停止服务。</p><p>我们看测试结果：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/QFzRdz9libEaO7cicciaPtp3yI5mTqpl2TAolwibmFk2p5o5czMibJ0f4af5WPFdXEMxz9VLq2ZUXukDtWMEbhR2wPA/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/QFzRdz9libEaO7cicciaPtp3yI5mTqpl2TAuD04d9egahMLicJynVyMqicic22W6UhyicQo4Bk5BV5Hx8fs32MtxWFHvw/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>很明显，他也出发了线程的 interrupt 方法导致线程报错，原理和 kill -15 差不多。</p><h3 id="_3actuator" tabindex="-1">③actuator <a class="header-anchor" href="#_3actuator" aria-label="Permalink to &quot;③actuator&quot;">​</a></h3><p>这种方式是通过引入依赖的方式停止服务，actuator 提供了很多接口，比如健康检查，基本信息等等，我们也可以使用他来优雅的停机。</p><p>引入依赖：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">&lt;dependency&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">            &lt;artifactId&gt;spring-boot-starter-actuator&lt;/artifactId&gt;</span></span>
<span class="line"><span style="color:#A6ACCD;">&lt;/dependency&gt;</span></span></code></pre></div><p>application.yml：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">server:</span></span>
<span class="line"><span style="color:#A6ACCD;">  port: 9988</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">management:</span></span>
<span class="line"><span style="color:#A6ACCD;">  endpoints:</span></span>
<span class="line"><span style="color:#A6ACCD;">    web:</span></span>
<span class="line"><span style="color:#A6ACCD;">      exposure:</span></span>
<span class="line"><span style="color:#A6ACCD;">        include: shutdown</span></span>
<span class="line"><span style="color:#A6ACCD;">  endpoint:</span></span>
<span class="line"><span style="color:#A6ACCD;">    shutdown:</span></span>
<span class="line"><span style="color:#A6ACCD;">      enabled: true</span></span>
<span class="line"><span style="color:#A6ACCD;">  server:</span></span>
<span class="line"><span style="color:#A6ACCD;">    port: 8888</span></span></code></pre></div><p>我这里对 actuator 的接口重新给定了一个接口，这样可提高安全性，下面我们来测试一下：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">@RequestMapping(value = &quot;/test&quot;,method = RequestMethod.GET)</span></span>
<span class="line"><span style="color:#A6ACCD;">    public String test(){</span></span>
<span class="line"><span style="color:#A6ACCD;">        System.out.println(&quot;test --- start&quot;);</span></span>
<span class="line"><span style="color:#A6ACCD;">        try {</span></span>
<span class="line"><span style="color:#A6ACCD;">            Thread.sleep(10000);</span></span>
<span class="line"><span style="color:#A6ACCD;">        } catch (InterruptedException e) {</span></span>
<span class="line"><span style="color:#A6ACCD;">            e.printStackTrace();</span></span>
<span class="line"><span style="color:#A6ACCD;">        }</span></span>
<span class="line"><span style="color:#A6ACCD;">        System.out.println(&quot;test --- end&quot;);</span></span>
<span class="line"><span style="color:#A6ACCD;">        return &quot;hello&quot;;</span></span>
<span class="line"><span style="color:#A6ACCD;">    }</span></span></code></pre></div><p>在请求 test 途中停止服务：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/QFzRdz9libEaO7cicciaPtp3yI5mTqpl2TAEfXQIw8cPcxddicKicXusl4icxYzjSAzSEMVOy6pAmyib85fuacIdur48w/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>我们发现发送停止服务请求之后还给我们返回了提示信息，很人性化，我们看看控制台：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/QFzRdz9libEaO7cicciaPtp3yI5mTqpl2TAHfpQDeNuamgvnHUUe0WC4zdZWPVoGw28jA4lUMjViaPVNZyC1kfFjZw/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/QFzRdz9libEaO7cicciaPtp3yI5mTqpl2TA3rlsoRNJpGLZNPleKTlTGWymbibKt9hP92JTnA514ibeZA2UnAIvdyibg/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>test — end 被执行了，不过在停止线程池的时候还是调用了线程的 interrupt 方法，导致 sleep 报错，这三种方式都可以比较优雅的停止 SpringBoot 服务。</p><p>如果我项目中存在线程休眠，我希望 10 秒以后再停止服务可以吗？肯定是可以的，我们只需要稍微做点修改就可以了。</p><p>新增停止 SpringBoot 服务类：ElegantShutdownConfig.java。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">package com.ymy.config;</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">import org.apache.catalina.connector.Connector;</span></span>
<span class="line"><span style="color:#A6ACCD;">import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;</span></span>
<span class="line"><span style="color:#A6ACCD;">import org.springframework.context.ApplicationListener;</span></span>
<span class="line"><span style="color:#A6ACCD;">import org.springframework.context.event.ContextClosedEvent;</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">import java.util.concurrent.Executor;</span></span>
<span class="line"><span style="color:#A6ACCD;">import java.util.concurrent.ThreadPoolExecutor;</span></span>
<span class="line"><span style="color:#A6ACCD;">import java.util.concurrent.TimeUnit;</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">public class ElegantShutdownConfig implements TomcatConnectorCustomizer, ApplicationListener&lt;ContextClosedEvent&gt; {</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">    private volatile Connector connector;</span></span>
<span class="line"><span style="color:#A6ACCD;">    private final int waitTime = 10;</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">    @Override</span></span>
<span class="line"><span style="color:#A6ACCD;">    public void customize(Connector connector) {</span></span>
<span class="line"><span style="color:#A6ACCD;">        this.connector = connector;</span></span>
<span class="line"><span style="color:#A6ACCD;">    }</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">    @Override</span></span>
<span class="line"><span style="color:#A6ACCD;">    public void onApplicationEvent(ContextClosedEvent event) {</span></span>
<span class="line"><span style="color:#A6ACCD;">        connector.pause();</span></span>
<span class="line"><span style="color:#A6ACCD;">        Executor executor = connector.getProtocolHandler().getExecutor();</span></span>
<span class="line"><span style="color:#A6ACCD;">        if (executor instanceof ThreadPoolExecutor) {</span></span>
<span class="line"><span style="color:#A6ACCD;">            try {</span></span>
<span class="line"><span style="color:#A6ACCD;">                ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;</span></span>
<span class="line"><span style="color:#A6ACCD;">                threadPoolExecutor.shutdown();</span></span>
<span class="line"><span style="color:#A6ACCD;">                if (!threadPoolExecutor.awaitTermination(waitTime, TimeUnit.SECONDS)) {</span></span>
<span class="line"><span style="color:#A6ACCD;">                    System.out.println(&quot;请尝试暴力关闭&quot;);</span></span>
<span class="line"><span style="color:#A6ACCD;">                }</span></span>
<span class="line"><span style="color:#A6ACCD;">            } catch (InterruptedException ex) {</span></span>
<span class="line"><span style="color:#A6ACCD;">                System.out.println(&quot;异常了&quot;);</span></span>
<span class="line"><span style="color:#A6ACCD;">                Thread.currentThread().interrupt();</span></span>
<span class="line"><span style="color:#A6ACCD;">            }</span></span>
<span class="line"><span style="color:#A6ACCD;">        }</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">    }</span></span>
<span class="line"><span style="color:#A6ACCD;">}</span></span></code></pre></div><p>在启动类中加入 bean：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">package com.ymy;</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">import com.ymy.config.ElegantShutdownConfig;</span></span>
<span class="line"><span style="color:#A6ACCD;">import lombok.extern.slf4j.Slf4j;</span></span>
<span class="line"><span style="color:#A6ACCD;">import org.apache.catalina.connector.Connector;</span></span>
<span class="line"><span style="color:#A6ACCD;">import org.springframework.boot.SpringApplication;</span></span>
<span class="line"><span style="color:#A6ACCD;">import org.springframework.boot.autoconfigure.SpringBootApplication;</span></span>
<span class="line"><span style="color:#A6ACCD;">import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;</span></span>
<span class="line"><span style="color:#A6ACCD;">import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;</span></span>
<span class="line"><span style="color:#A6ACCD;">import org.springframework.boot.web.servlet.server.ServletWebServerFactory;</span></span>
<span class="line"><span style="color:#A6ACCD;">import org.springframework.context.ApplicationListener;</span></span>
<span class="line"><span style="color:#A6ACCD;">import org.springframework.context.ConfigurableApplicationContext;</span></span>
<span class="line"><span style="color:#A6ACCD;">import org.springframework.context.annotation.Bean;</span></span>
<span class="line"><span style="color:#A6ACCD;">import org.springframework.context.event.ContextClosedEvent;</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">import java.util.concurrent.Executor;</span></span>
<span class="line"><span style="color:#A6ACCD;">import java.util.concurrent.ThreadPoolExecutor;</span></span>
<span class="line"><span style="color:#A6ACCD;">import java.util.concurrent.TimeUnit;</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">@SpringBootApplication</span></span>
<span class="line"><span style="color:#A6ACCD;">public class ShutdownServerApplication {</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">    public static void main(String[] args) {</span></span>
<span class="line"><span style="color:#A6ACCD;">        ConfigurableApplicationContext run = SpringApplication.run(ShutdownServerApplication.class, args);</span></span>
<span class="line"><span style="color:#A6ACCD;">        run.registerShutdownHook();</span></span>
<span class="line"><span style="color:#A6ACCD;">    }</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">    @Bean</span></span>
<span class="line"><span style="color:#A6ACCD;">    public ElegantShutdownConfig elegantShutdownConfig() {</span></span>
<span class="line"><span style="color:#A6ACCD;">        return new ElegantShutdownConfig();</span></span>
<span class="line"><span style="color:#A6ACCD;">    }</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">    @Bean</span></span>
<span class="line"><span style="color:#A6ACCD;">    public ServletWebServerFactory servletContainer() {</span></span>
<span class="line"><span style="color:#A6ACCD;">        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();</span></span>
<span class="line"><span style="color:#A6ACCD;">        tomcat.addConnectorCustomizers(elegantShutdownConfig());</span></span>
<span class="line"><span style="color:#A6ACCD;">        return tomcat;</span></span>
<span class="line"><span style="color:#A6ACCD;">    }</span></span>
<span class="line"><span style="color:#A6ACCD;">}</span></span></code></pre></div><p>这样我们就配置好了，我们再来测试一遍，test 的接口还是休眠 10 秒：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/QFzRdz9libEaO7cicciaPtp3yI5mTqpl2TAPEfGQBTib3oAoUsNBEavp6Yx2lq6MkDicVyuicfSDVf1tHnzDLg6thnCA/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>我们发现这次没有报错了，他是等待了一段时间之后再结束的线程池，这个时间就是我们在 ElegantShutdownConfig 类中配置的 waitTime。</p><p>那可能你会有疑问了，JVM 没有立即停止，那这个时候在有请求会发生什么呢？如果关闭的时候有新的请求，服务将不在接收此请求。</p><h3 id="数据备份操作" tabindex="-1">数据备份操作 <a class="header-anchor" href="#数据备份操作" aria-label="Permalink to &quot;数据备份操作&quot;">​</a></h3><p>如果我想在服务停止的时候做点备份操作啥的，应该怎么做呢？其实很简单在你要执行的方法上添加一个注解即可：@PreDestroy。</p><ul><li>Destroy：消灭、毁灭。</li><li>pre：前缀缩写。</li></ul><p>所以合在一起的意思就是在容器停止之前执行一次，你可以在这里面做备份操作，也可以做记录停机时间等。</p><p>新增服务停止备份工具类：DataBackupConfig.java。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">package com.ymy.config;</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">import org.springframework.context.annotation.Configuration;</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">import javax.annotation.PreDestroy;</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">@Configuration</span></span>
<span class="line"><span style="color:#A6ACCD;">public class DataBackupConfig {</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">    @PreDestroy</span></span>
<span class="line"><span style="color:#A6ACCD;">    public  void backData(){</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">        System.out.println(&quot;正在备份数据。。。。。。。。。。。&quot;);</span></span>
<span class="line"><span style="color:#A6ACCD;">    }</span></span>
<span class="line"><span style="color:#A6ACCD;">}</span></span></code></pre></div><p>我们再来测试然后打印控制台日志：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/QFzRdz9libEaO7cicciaPtp3yI5mTqpl2TAZP0wVm99mPyMekuNHTo6a7RFfxrMtc52ViaMNiaFUxia270XoRJfXpKvQ/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/QFzRdz9libEaO7cicciaPtp3yI5mTqpl2TAzINT8epCK1s0QibY3GUib4V3xt2wddXH5lw639BCxFxziccIhEgJT1uFg/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><h1 id="linux服务器最大tcp连接" tabindex="-1">Linux服务器最大TCP连接 <a class="header-anchor" href="#linux服务器最大tcp连接" aria-label="Permalink to &quot;Linux服务器最大TCP连接&quot;">​</a></h1><h2 id="困惑很多人的并发问题" tabindex="-1">困惑很多人的并发问题 <a class="header-anchor" href="#困惑很多人的并发问题" aria-label="Permalink to &quot;困惑很多人的并发问题&quot;">​</a></h2><p>在网络开发中，我发现有很多同学对一个基础问题始终是没有彻底搞明白。那就是一台服务器最大究竟能支持多少个网络连接？我想我有必要单独发一篇文章来好好说一下这个问题。</p><blockquote><p>很多同学看到这个问题的第一反应是65535。原因是：“听说端口号最多有65535个，那长连接就最多保持65535个了。”是这样的吗？还有的人说：“应该受TCP连接里四元组的空间大小限制，算起来是200多万亿个！”</p></blockquote><p>如果你对这个问题也是理解得不够彻底，那么今天讲个故事讲给你听！</p><h2 id="一次关于服务器端并发的聊天" tabindex="-1">一次关于服务器端并发的聊天 <a class="header-anchor" href="#一次关于服务器端并发的聊天" aria-label="Permalink to &quot;一次关于服务器端并发的聊天&quot;">​</a></h2><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwoo5ibkEGbrfCkOXicTNTjPGxzv6h8iaQXTt7zGndbmn4sht6iasE6Y5LdW64ZAgdkxibTtah5qyGoMKqQ/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><blockquote><p>&quot;TCP连接四元组是源IP地址、源端口、目的IP地址和目的端口。任意一个元素发生了改变，那么就代表的是一条完全不同的连接了。拿我的Nginx举例，它的端口是固定使用80。另外我的IP也是固定的，这样目的IP地址、目的端口都是固定的。剩下源IP地址、源端口是可变的。所以理论上我的Nginx上最多可以建立2的32次方（ip数）×2的16次方（port数）个连接。这是两百多万亿的一个大数字！！&quot;</p></blockquote><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwoo5ibkEGbrfCkOXicTNTjPGxzjVPBaZFsRWxsP4PT92osvJcEicb4giceBWX3pO37OnI6qCDiaeHZ63Pg/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><blockquote><p>&quot;进程每打开一个文件（linux下一切皆文件，包括socket），都会消耗一定的内存资源。如果有不怀好心的人启动一个进程来无限地创建和打开新的文件，会让服务器崩溃。所以linux系统出于安全角度的考虑，在多个位置都限制了可打开的文件描述符的数量，包括系统级、用户级、进程级。这三个限制的含义和修改方式如下：&quot;</p></blockquote><ul><li>系统级：当前系统可打开的最大数量，通过fs.file-max参数可修改</li><li>用户级：指定用户可打开的最大数量，修改/etc/security/limits.conf</li><li>进程级：单个进程可打开的最大数量，通过fs.nr_open参数可修改</li></ul><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwoo5ibkEGbrfCkOXicTNTjPGxbO8LmdRkuWzWnGMGR2uG5luAtmDxb11XRjq17ntiasSHbwf5NEZf7hA/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><blockquote><p>&quot;我的接收缓存区大小是可以配置的，通过sysctl命令就可以查看。&quot;</p></blockquote><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">$ sysctl -a | grep rmem</span></span>
<span class="line"><span style="color:#A6ACCD;">net.ipv4.tcp_rmem = 4096 87380 8388608</span></span>
<span class="line"><span style="color:#A6ACCD;">net.core.rmem_default = 212992</span></span>
<span class="line"><span style="color:#A6ACCD;">net.core.rmem_max = 8388608</span></span></code></pre></div><blockquote><p>&quot;其中在tcp_rmem&quot;中的第一个值是为你们的TCP连接所需分配的最少字节数。该值默认是4K，最大的话8MB之多。也就是说你们有数据发送的时候我需要至少为对应的socket再分配4K内存，甚至可能更大。&quot;</p></blockquote><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwoo5ibkEGbrfCkOXicTNTjPGxS9JZ4Rf3jw5Cic6k7yqkJuEn87oJahc7TO5wGkUBkh6P8YRTUFTINAA/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><blockquote><p>&quot;TCP分配发送缓存区的大小受参数net.ipv4.tcp_wmem配置影响。&quot;</p></blockquote><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">$ sysctl -a | grep wmem</span></span>
<span class="line"><span style="color:#A6ACCD;">net.ipv4.tcp_wmem = 4096 65536 8388608</span></span>
<span class="line"><span style="color:#A6ACCD;">net.core.wmem_default = 212992</span></span>
<span class="line"><span style="color:#A6ACCD;">net.core.wmem_max = 8388608</span></span></code></pre></div><blockquote><p>&quot;在net.ipv4.tcp_wmem&quot;中的第一个值是发送缓存区的最小值，默认也是4K。当然了如果数据很大的话，该缓存区实际分配的也会比默认值大。&quot;</p></blockquote><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwoo5ibkEGbrfCkOXicTNTjPGxKBBZ0b8hQGzMib9I0Sw4MlFfgVqt5QSMZDgBTwFa9aeVXN1coEpGArQ/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><h2 id="服务端百万连接达成记" tabindex="-1">服务端百万连接达成记 <a class="header-anchor" href="#服务端百万连接达成记" aria-label="Permalink to &quot;服务端百万连接达成记&quot;">​</a></h2><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwoo5ibkEGbrfCkOXicTNTjPGxibQjHJpozOYHaYGiaD3txd4MmGXcDThW96z7oMbH9PlVaaC417GblyKA/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><blockquote><p>“准备啥呢，还记得前面说过Linux对最大文件对象数量有限制，所以要想完成这个实验，得在用户级、系统级、进程级等位置把这个上限加大。我们实验目的是100W，这里都设置成110W，这个很重要！因为得保证做实验的时候其它基础命令例如ps，vi等是可用的。“</p></blockquote><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwoo5ibkEGbrfCkOXicTNTjPGxVHMr5VAUIcFpS1P5bcUnAe9lGkkn8kd6hGAYl5w7h3x7EqV2qt4WDQ/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwoo5ibkEGbrfCkOXicTNTjPGxprMrmcJjPQc142jpJNg0piauyFgqn0ic4lwuK5Na8S7lk3NLENhEOxJA/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>活动连接数量确实达到了100W：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">$ ss -n | grep ESTAB | wc -l  </span></span>
<span class="line"><span style="color:#A6ACCD;">1000024</span></span></code></pre></div><p>当前机器内存总共是3.9GB，其中内核Slab占用了3.2GB之多。MemFree和Buffers加起来也只剩下100多MB了：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">$ cat /proc/meminfo</span></span>
<span class="line"><span style="color:#A6ACCD;">MemTotal:        3922956 kB</span></span>
<span class="line"><span style="color:#A6ACCD;">MemFree:           96652 kB</span></span>
<span class="line"><span style="color:#A6ACCD;">MemAvailable:       6448 kB</span></span>
<span class="line"><span style="color:#A6ACCD;">Buffers:           44396 kB</span></span>
<span class="line"><span style="color:#A6ACCD;">......</span></span>
<span class="line"><span style="color:#A6ACCD;">Slab:          3241244KB kB</span></span></code></pre></div><p>通过slabtop命令可以查看到densty、flip、sock_inode_cache、TCP四个内核对象都分别有100W个：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwoo5ibkEGbrfCkOXicTNTjPGxuw4Y9XO0IHuzkHBwnCFTSkJRvKYwlwibv1kvMibfPcEBaiaVDekMtXWYA/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwoo5ibkEGbrfCkOXicTNTjPGxPkdoiaTrf5Sdzq4ibuIIB8mN5YqjlSPR1JLTmcIdss3RJqs7XnvNNmSA/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><h1 id="linux服务端最大并发数" tabindex="-1">Linux服务端最大并发数 <a class="header-anchor" href="#linux服务端最大并发数" aria-label="Permalink to &quot;Linux服务端最大并发数&quot;">​</a></h1><h2 id="开场白" tabindex="-1">开场白 <a class="header-anchor" href="#开场白" aria-label="Permalink to &quot;开场白&quot;">​</a></h2><p>在开始今天的文章之前，先抛一个面试题出来：</p><blockquote><p>你接触过的单机最大并发数是多少？ 你认为当前正常配置的服务器物理机最大并发数可以到多少？ 说说你的理解和分析。</p></blockquote><p>思考几分钟，如果你可以<strong>有理有据地说出答案</strong>，那确实就不用再往下看了，关上手机去陪陪家人是个不错的选择。</p><p>思考几分钟，如果你<strong>没有头绪或者对答案不确定</strong>，那么你先不用着急关闭页面去玩耍，你应该继续往下看，因为这个问题很不错。</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/wAkAIFs11qZibu6QZauU9zUcre7RvLf7icChfuS7diaTcxlfhqoDtywqvSBECicHuwjENAxfCMpsicykWGYMQ0keXKg/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>对于后端开发人员来说，并发数往往和技术难度是呈正相关的，实际上也确实如此：<strong>体量决定架构</strong>。</p><p>服务端根据不同业务场景会有不同的侧重点，单纯追求高并发其实并不是根本目的，<strong>高可用&amp;稳定性更重要</strong>。</p><p>所以最终我们的目的是：<strong>保证高可用高稳定的基础上追求高并发，降本增效</strong>。</p><p>高可用&amp;高并发是我们直观感受到的，本质上这是个<strong>复杂的系统工程</strong>，每个环节都会影响结果，每一块都值得研究和深入。</p><img src="https://mmbiz.qpic.cn/mmbiz_png/wAkAIFs11qZibu6QZauU9zUcre7RvLf7ic9xdUEcyPezq66oDWiaHc0Dewu9A48duaFMn2rt84n7PmWKg92ibcx7icA/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片" style="zoom:80%;"><p>本文通过一道面试题切入，先描述了C10K和C10M问题，进而详细说明了客户端的最大访问数和服务端的最大并发数计算和原理，最后描述了NAT场景下的访问并发数。</p><blockquote><p>虽然理论服务端并发数非常大，但是我们也没有必要觉得并发数高就厉害，服务复杂程度不一样，<strong>切忌唯并发数来判断业务和开发者水平</strong>。试想echo服务和订单交易服务显然是不一样的，我们<strong>应该做的是在服务稳定和高可用的前提下去从缓存/网络/数据库等多个角度来优化提高性能</strong>。</p></blockquote><h2 id="c10k问题和c10m问题" tabindex="-1">C10K问题和C10M问题 <a class="header-anchor" href="#c10k问题和c10m问题" aria-label="Permalink to &quot;C10K问题和C10M问题&quot;">​</a></h2><p>在2000年初的时候，全球互联网的规模并不大，但是当时就已经提出了C10K问题，所谓<strong>C10K就是单机1w并发问题</strong>，虽然现在不觉得是个难题了，但是这在当初是很有远见和挑战的问题。</p><img src="https://mmbiz.qpic.cn/mmbiz_png/wAkAIFs11qZibu6QZauU9zUcre7RvLf7icjWfXEVZu70MOQuhKiaANIRz8ytYhsJO20dXAeusiaNsYgjA2hCuV9HKA/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片" style="zoom:67%;"><p>C10K问题最早由<strong>Dan Kegel</strong>发布于其个人站点，原文链接如下:</p><blockquote><p><strong><a href="http://www.kegel.com/c10k.html" target="_blank" rel="noreferrer">http://www.kegel.com/c10k.html</a></strong></p></blockquote><p>相关资料显示Dan Kegel目前工作于<strong>Google</strong>，从1978年起开始接触计算机编程，是Winetricks和Crosstool的作者，大佬年轻时的照片：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/wAkAIFs11qZibu6QZauU9zUcre7RvLf7ic5MjAZNctyPzKGYicZp4SUMUqILWVJ4FsM8Xrc7ZzaQL3Pk3GyLjUxNA/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>Dan Kegel这篇文章阅读难度并不大，大白建议从事服务端开发或者对高性能网络开发有兴趣的读者尝试读一读。</p><p>在APUE第三版都没有提到epoll，所以<strong>我们解决C10K问题的时间并不长</strong>，其中IO复用epoll/kqueue/iocp等技术对于C10k问题的解决起到了非常重要的作用。</p><p>开源大神们基于epoll/kqueue等开发了诸如libevent/libuv等网络库，从而大幅提高了高并发网络的开发效率，对于C/C++程序员来说并不陌生。</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/wAkAIFs11qZibu6QZauU9zUcre7RvLf7icwrVRF3kSwvMdsge6KrdiaEQGVibzic7uBOZw851iclbQ2cm1tXssWpwuQw/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>这里简单提一下针对下一个10年的展望和挑战：<strong>C10M问题</strong>。</p><p>站在浪尖的那一批人早就开始思考<strong>让单机达到1000w并发</strong>，现在听起来感觉不可思议，但是要达到这个目标，除了硬件上的提升，更重要的是<strong>对系统软件和协议栈的改造</strong>。</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/wAkAIFs11qZibu6QZauU9zUcre7RvLf7icQlvML1DLvvwrULdzdjUqkpDwmWhmmKZNJ4picZX3mv5Mx06tt2zaU8Q/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>Errata Security的CEO Robert Graham在Shmoocon 2013大会上的演讲，大佬重要的观点是：</p><blockquote><p><strong>不要让OS内核执行所有繁重的任务：将数据包处理、内存管理、处理器调度等任务从内核转移到应用程序高效地完成，让诸如Linux这样的OS只处理控制层，数据层完全交给应用程序来处理。</strong></p></blockquote><p>确实也是如此，<strong>难道你不觉得Linux内核做了太多不该自己做的事情了吗</strong>？</p><p>近几年出现的DPDK、PFRING、NETMAP等技术也是类似的思想，现在流行的协处理器+CPU的架构也是这样的：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/wAkAIFs11qZibu6QZauU9zUcre7RvLf7icL04E6OJbCnpnibQ3BTYEpNs46Q3kpcSfMqK13x4duN69oR9gn2GV4Uw/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><h2 id="服务器最大并发数分析" tabindex="-1">服务器最大并发数分析 <a class="header-anchor" href="#服务器最大并发数分析" aria-label="Permalink to &quot;服务器最大并发数分析&quot;">​</a></h2><p>前面提到的C10K和C10M问题都是围绕着提升服务器并发能力展开的，但是难免要问：<strong>服务器最大的并发上限是多少</strong>？</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/wAkAIFs11qZibu6QZauU9zUcre7RvLf7icib5m03SiayEibcsHCaYnVlb03af2JmDdEeGHA9JfEYHaxk4z3ARuxhNQA/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><h3 id="_1-五元组" tabindex="-1">1 五元组 <a class="header-anchor" href="#_1-五元组" aria-label="Permalink to &quot;1 五元组&quot;">​</a></h3><p>做过通信的盆友们一定听过<strong>五元组</strong>这个概念，一个五元组可以唯一标记一个网络连接，所以要理解和分析最大并发数，就必须理解五元组：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/wAkAIFs11qZibu6QZauU9zUcre7RvLf7icnBd55Fem053fREQZ1wOzr4wviaBYrs3sjxtiaOd7WznhA7JnjZ1RSGkA/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>这样的话，就可以基本认为：<strong>理论最大并发数 = 服务端唯一五元组数</strong>。</p><h3 id="_2-端口-ip组合数" tabindex="-1">2 端口&amp;IP组合数 <a class="header-anchor" href="#_2-端口-ip组合数" aria-label="Permalink to &quot;2 端口&amp;IP组合数&quot;">​</a></h3><p>那么对于服务器来说，服务端唯一五元组数最大是多少呢？</p><p><strong>有人说是65535</strong>，显然不是，但是之所以会有这类答案是因为当前Linux的端口号是2字节大小的short类型，总计2^16个端口，除去一些系统占用的端口，可用端口确实只剩下64000多了。</p><p>对于服务端本身来说，DestPort数量确实有限，假定有多张网卡，每个网卡绑定多个IP，<strong>服务端的Port端口数和IP数的组合类型也是有限的</strong>。</p><p>对于客户端来说，本身的端口和IP也是一样有限的，虽然这是个<strong>组合问题</strong>，但是数量还是有限的：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/wAkAIFs11qZibu6QZauU9zUcre7RvLf7icNcicTDq68qlIoeZu5cINXz3EQIHGKUy4FaOVKUpC2UqdJAPeFVFInxw/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><h3 id="_3-并发数理论极限" tabindex="-1">3 并发数理论极限 <a class="header-anchor" href="#_3-并发数理论极限" aria-label="Permalink to &quot;3 并发数理论极限&quot;">​</a></h3><p>看了前面的端口&amp;IP的组合数计算，好像并发数并不会特别大。</p><p><strong>错了，是真的会很大。</strong></p><p>分析一下，前面的计算都是针对单个服务器或者客户端的，但是<strong>实际上每个服务器会应对全网的所有客户端</strong>，那么从服务端看，源IP和源Port的数量是非常大的。</p><p><strong>理论上服务端可以接受的客户端IP是2^32(按照IPv4计算）,端口数是2^16，目前端口号仍然是16bit的，所有这个理论最大值是2^48</strong>，果然很大！</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/wAkAIFs11qZibu6QZauU9zUcre7RvLf7icxJDaILeLKoAdBa4t7AK4w5h0eF9OITKyrZFnDRtLRkibKBUGIcPw4tA/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><h3 id="_4-实际情况" tabindex="-1">4 实际情况 <a class="header-anchor" href="#_4-实际情况" aria-label="Permalink to &quot;4 实际情况&quot;">​</a></h3><p>天下没有免费的午餐。</p><p><strong>每一条连接都是要消耗系统资源的</strong>，所以实际中可能会设置最大并发数来保证服务器的安全和稳定，所以<strong>这个理论最大并发数是不可能达到的</strong>。</p><p><strong>实际中并发数和业务是直接相关的</strong>，像Redis这种内存型的服务端并发十几万都是没问题的，大部分来讲几十/几百/几千/几万等是存在的。</p><h2 id="客户端最大连接数" tabindex="-1">客户端最大连接数 <a class="header-anchor" href="#客户端最大连接数" aria-label="Permalink to &quot;客户端最大连接数&quot;">​</a></h2><p>理解了服务器的最大并发数是2^48，那么<strong>客户端最多可以连接多少服务器呢</strong>？</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/wAkAIFs11qZibu6QZauU9zUcre7RvLf7icrGoKbWnGGN6z6IavlPJMcMjzgWiaCJ3LTs1vz1ia1icT9zWjTJia1rhIFw/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>对于客户端来说，当然可以借助于多网卡多IP来增加连接能力，我们仍然假定客户端只有1张网卡1个IP，由于端口数的限制到2^16，再去掉系统占用的端口，剩下可用的差不多64000。</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/wAkAIFs11qZibu6QZauU9zUcre7RvLf7icVMZ1MToDCeG3icPopDLezsuqkNuQicEewTqPk4dA7HTNmAEcGJiathRDw/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>也就是说，客户端虽然可以连接任意的目的IP和目的端口，但是客户端自身端口是有限的，所以<strong>客户端的理论最大连接数是2^16</strong>，含系统占用端口。</p><h2 id="nat环境下的客户端" tabindex="-1">NAT环境下的客户端 <a class="header-anchor" href="#nat环境下的客户端" aria-label="Permalink to &quot;NAT环境下的客户端&quot;">​</a></h2><p>解决前面的两个问题之后，来看另外一个问题：</p><blockquote><p><strong>一个公网出口NAT服务设备最多可同时支持多少内网IP并发访问外网服务？</strong></p></blockquote><p>毕竟公网IP都是有限并且要花钱的，我们大部分机器都是在局域网中结合NAT来进行外网访问的，所以这个场景还是很熟悉的。来看下<strong>内网机器访问外网时的IP&amp;端口替换和映射还原的过程</strong>，就明白了：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/wAkAIFs11qZibu6QZauU9zUcre7RvLf7ic4vCCiaibz3fagWs7UsWxQWUjfc8HTb6jsSe00icoka7WPZAkeLM9au4lA/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>因为这时的客户端是NAT设备，所以NAT环境下最多支持65535个并发访问外网。</p><h1 id="linux-中-cpu-利用率是如何算出来的" tabindex="-1">Linux 中 CPU 利用率是如何算出来的 <a class="header-anchor" href="#linux-中-cpu-利用率是如何算出来的" aria-label="Permalink to &quot;Linux 中 CPU 利用率是如何算出来的&quot;">​</a></h1><p>在线上服务器观察线上服务运行状态的时候，绝大多数人都是喜欢先用 top 命令看看当前系统的整体 cpu 利用率。例如，随手拿来的一台机器，top 命令显示的利用率信息如下：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwqH85vreK5IDjV8DfNTUBfBZJ1IO0dcFhWIEp35apYI01n9TcDUdRxdJRtgZ5EO9A6iaoBykIBMslg/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>这个输出结果说简单也简单，说复杂也不是那么容易就能全部搞明白的。例如：</p><p>问题 1：top 输出的利用率信息是如何计算出来的，它精确吗？ 问题 2：ni 这一列是 nice，它输出的是 cpu 在处理啥时的开销？ 问题 3：wa 代表的是 io wait，那么这段时间中 cpu 到底是忙碌还是空闲？</p><p>今天我们对 cpu 利用率统计进行深入的学习。通过今天的学习，你不但能了解 cpu 利用率统计实现细节，还能对 nice、io wait 等指标有更深入的理解。今天我们先从自己的思考开始！</p><h2 id="先思考一下" tabindex="-1">先思考一下 <a class="header-anchor" href="#先思考一下" aria-label="Permalink to &quot;先思考一下&quot;">​</a></h2><p>抛开 Linux 的实现先不谈，如果有如下需求，有一个四核服务器，上面跑了四个进程。</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwqH85vreK5IDjV8DfNTUBfBbGAnytO2s1NhVwAv5FEXGtZoJeCTejMCM4LXDGsEgSdG2TNzjthVJQ/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>让你来设计计算整个系统 cpu 利用率的这个需求，支持像 top 命令这样的输出，满足以下要求：</p><ul><li>cpu 使用率要尽可能地准确；</li><li>要尽可能地体现秒级瞬时 cpu 状态。</li></ul><p>可以先停下来思考几分钟。</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwqH85vreK5IDjV8DfNTUBfB6u7zIo27yQNKJThIJr1v4DMSDojdUOcIMWF4VRczayrEtvib24uTCfQ/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>好，思考结束。经过思考你会发现，这个看起来很简单的需求，实际还是有点小复杂的。</p><p>其中一个思路是把所有进程的执行时间都加起来，然后再除以系统执行总时间*4。</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwqH85vreK5IDjV8DfNTUBfBYf5lcGdFEETunSkXRMACwGG4UORpqb9KjVV9NDHzPpTN5diah1gXibHw/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>这个思路是没问题的，用这种方法统计很长一段时间内的 cpu 利用率是可以的，统计也足够的准确。</p><p>但只要用过 top 你就知道 top 输出的 cpu 利用率并不是长时间不变的，而是默认 3 秒为单位会动态更新一下（这个时间间隔可以使用 -d 设置）。我们的这个方案体现总利用率可以，体现这种瞬时的状态就难办了。你可能会想到那我也 3 秒算一次不就行了？但这个 3 秒的时间从哪个点开始呢。粒度很不好控制。</p><p>上一个思路问题核心就是如何解决瞬时问题。提到瞬时状态，你可能就又来思路了。那我就用瞬时采样去看，看看当前有几个核在忙。四个核中如果有两个核在忙，那利用率就是 50%。</p><p>这个思路思考的方向也是正确的，但是问题有两个：</p><ul><li>你算出的数字都是 25% 的整数倍；</li><li>这个瞬时值会导致 cpu 使用率显示的剧烈震荡。</li></ul><p>比如下图：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwqH85vreK5IDjV8DfNTUBfB5FlNsUpWn5TUeAWuJLfGLwq8zx9NFcUvSib6oxDLQMvvs8VKYLlogog/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>在 t1 的瞬时状态看来，系统的 cpu 利用率毫无疑问就是 100%，但在 t2 时间看来，使用率又变成 0% 了。思路方向是对的，但显然这种粗暴的计算无法像 top 命令一样优雅地工作。</p><p>我们再改进一下它，把上面两个思路结合起来，可能就能解决我们的问题了。在采样上，我们把周期定得细一些，但在计算上我们把周期定得粗一些。</p><p>我们引入采用周期的概念，定时比如每 1 毫秒采样一次。如果采样的瞬时，cpu 在运行，就将这 1 ms 记录为使用。这时会得出一个瞬时的 cpu 使用率，把它都存起来。</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwqH85vreK5IDjV8DfNTUBfBictzQPdfGp0Jicl0VmiaVx0KkuM9ufzYicLGiaWMCnxYSBnzZUcyqnSWN1A/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>在统计 3 秒内的 cpu 使用率的时候，比如上图中的 t1 和 t2 这段时间范围。那就把这段时间内的所有瞬时值全加一下，取个平均值。这样就能解决上面的问题了，统计相对准确，避免了瞬时值剧烈震荡且粒度过粗（只能以 25% 为单位变化）的问题了。</p><p>可能有同学会问了，假如 cpu 在两次采样中间发生变化了呢，如下图这种情况。</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwqH85vreK5IDjV8DfNTUBfBn2Sm8MoDSicsHEOficN0WibQQwl1zaibcpcKMjuTR6aTM8O2L3Sm30hfFw/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>在当前采样点到来的时候，进程 A 其实刚执行完，有一点点时间既没被上一个采样点统计到，本次也统计不到。对于进程 B，其实只开始了一小段时间，把 1 ms 全记上似乎有点多记了。</p><p>确实会存在这个问题，但因为我们的采样是 1 ms 一次，而我们实际查看使用的时候最少也是秒级别地用，会包括有成千上万个采样点的信息，所以这种误差并不会影响我们对全局的把握。</p><p>事实上，Linux 也就是这样来统计系统 cpu 利用率的。虽然可能会有误差，但作为一项统计数据使用已经是足够了的。在实现上，Linux 是将所有的瞬时值都累加到某一个数据上的，而不是真的存了很多份的瞬时数据。</p><p>接下来就让我们进入 Linux 来查看它对系统 cpu 利用率统计的具体实现。</p><h2 id="top-命令使用数据在哪儿" tabindex="-1">top 命令使用数据在哪儿 <a class="header-anchor" href="#top-命令使用数据在哪儿" aria-label="Permalink to &quot;top 命令使用数据在哪儿&quot;">​</a></h2><p>上一节我们说的 Linux 在实现上是将瞬时值都累加到某一个数据上的，这个值是内核通过 /proc/stat 伪文件来对用户态暴露。Linux 在计算系统 cpu 利用率的时候用的就是它。</p><p>整体上看，top 命令工作的内部细节如下图所示。</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwqH85vreK5IDjV8DfNTUBfBhHebNVZKmVicHjKjmVLj9AuQzgHEpZykq25GjJLfZlVZhX1JTGnX0DQ/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><ul><li>top 命令访问 /proc/stat 获取各项 cpu 利用率使用值；</li><li>内核调用 stat_open 函数来处理对 /proc/stat 的访问；</li><li>内核访问的数据来源于 kernel_cpustat 数组，并汇总；</li><li>打印输出给用户态。</li></ul><p>接下来我们把每一步都展开来详细看看。</p><p>通过使用 strace 跟踪 top 命令的各种系统调用，可以看到它对该文件的调用。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;"># strace top</span></span>
<span class="line"><span style="color:#A6ACCD;">...</span></span>
<span class="line"><span style="color:#A6ACCD;">openat(AT_FDCWD, &quot;/proc/stat&quot;, O_RDONLY) = 4</span></span>
<span class="line"><span style="color:#A6ACCD;">openat(AT_FDCWD, &quot;/proc/2351514/stat&quot;, O_RDONLY) = 8</span></span>
<span class="line"><span style="color:#A6ACCD;">openat(AT_FDCWD, &quot;/proc/2393539/stat&quot;, O_RDONLY) = 8</span></span>
<span class="line"><span style="color:#A6ACCD;">...</span></span></code></pre></div><blockquote><p>除了 /proc/stat 外，还有各个进程细分的 /proc/{pid}/stat，是用来计算各个进程的 cpu 利用率时使用的。</p></blockquote><p>内核为各个伪文件都定义了处理函数，/proc/stat 文件的处理方法是 proc_stat_operations。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">//file:fs/proc/stat.c</span></span>
<span class="line"><span style="color:#A6ACCD;">static int __init proc_stat_init(void)</span></span>
<span class="line"><span style="color:#A6ACCD;">{</span></span>
<span class="line"><span style="color:#A6ACCD;"> proc_create(&quot;stat&quot;, 0, NULL, &amp;proc_stat_operations);</span></span>
<span class="line"><span style="color:#A6ACCD;"> return 0;</span></span>
<span class="line"><span style="color:#A6ACCD;">}</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">static const struct file_operations proc_stat_operations = {</span></span>
<span class="line"><span style="color:#A6ACCD;"> .open  = stat_open,</span></span>
<span class="line"><span style="color:#A6ACCD;"> ...</span></span>
<span class="line"><span style="color:#A6ACCD;">};</span></span></code></pre></div><p>proc_stat_operations 中包含了该文件对应的操作方法。当打开 /proc/stat 文件的时候，stat_open 就会被调用到。stat_open 依次调用 single_open_size，show_stat 来输出数据内容。我们来看看它的代码：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">//file:fs/proc/stat.c</span></span>
<span class="line"><span style="color:#A6ACCD;">static int show_stat(struct seq_file *p, void *v)</span></span>
<span class="line"><span style="color:#A6ACCD;">{</span></span>
<span class="line"><span style="color:#A6ACCD;"> u64 user, nice, system, idle, iowait, irq, softirq, steal;</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;"> for_each_possible_cpu(i) {</span></span>
<span class="line"><span style="color:#A6ACCD;">  struct kernel_cpustat *kcs = &amp;kcpustat_cpu(i);</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">  user += kcs-&gt;cpustat[CPUTIME_USER];</span></span>
<span class="line"><span style="color:#A6ACCD;">  nice += kcs-&gt;cpustat[CPUTIME_NICE];</span></span>
<span class="line"><span style="color:#A6ACCD;">  system += kcs-&gt;cpustat[CPUTIME_SYSTEM];</span></span>
<span class="line"><span style="color:#A6ACCD;">  idle += get_idle_time(kcs, i);</span></span>
<span class="line"><span style="color:#A6ACCD;">  iowait += get_iowait_time(kcs, i);</span></span>
<span class="line"><span style="color:#A6ACCD;">  irq += kcs-&gt;cpustat[CPUTIME_IRQ];</span></span>
<span class="line"><span style="color:#A6ACCD;">  softirq += kcs-&gt;cpustat[CPUTIME_SOFTIRQ];</span></span>
<span class="line"><span style="color:#A6ACCD;">  ...</span></span>
<span class="line"><span style="color:#A6ACCD;"> }</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;"> //转换成节拍数并打印出来</span></span>
<span class="line"><span style="color:#A6ACCD;"> seq_put_decimal_ull(p, &quot;cpu  &quot;, nsec_to_clock_t(user));</span></span>
<span class="line"><span style="color:#A6ACCD;"> seq_put_decimal_ull(p, &quot; &quot;, nsec_to_clock_t(nice));</span></span>
<span class="line"><span style="color:#A6ACCD;"> seq_put_decimal_ull(p, &quot; &quot;, nsec_to_clock_t(system));</span></span>
<span class="line"><span style="color:#A6ACCD;"> seq_put_decimal_ull(p, &quot; &quot;, nsec_to_clock_t(idle));</span></span>
<span class="line"><span style="color:#A6ACCD;"> seq_put_decimal_ull(p, &quot; &quot;, nsec_to_clock_t(iowait));</span></span>
<span class="line"><span style="color:#A6ACCD;"> seq_put_decimal_ull(p, &quot; &quot;, nsec_to_clock_t(irq));</span></span>
<span class="line"><span style="color:#A6ACCD;"> seq_put_decimal_ull(p, &quot; &quot;, nsec_to_clock_t(softirq));</span></span>
<span class="line"><span style="color:#A6ACCD;"> ...</span></span>
<span class="line"><span style="color:#A6ACCD;">}</span></span></code></pre></div><p>在上面的代码中，for_each_possible_cpu 是在遍历存储着 cpu 使用率数据的 kcpustat_cpu 变量。该变量是一个 percpu 变量，它为每一个逻辑核都准备了一个数组元素。里面存储着当前核所对应各种事件，包括 user、nice、system、idel、iowait、irq、softirq 等。</p><p>在这个循环中，将每一个核的每种使用率都加起来。最后通过 seq_put_decimal_ull 将这些数据输出出来。</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwqH85vreK5IDjV8DfNTUBfBkVQhRkt2A4DKdA2dcJicchB1ObdAhF51JP9nMvdJriba6zUibOUom4ib3g/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>注意，在内核中实际每个时间记录的是纳秒数，但是在输出的时候统一都转化成了节拍单位。至于节拍单位多长，下一节我们介绍。总之， /proc/stat 的输出是从 kernel_cpustat 这个 percpu 变量中读取出来的。</p><p>我们接着再看看这个变量中的数据是何时加进来的。</p><h2 id="统计数据怎么来的" tabindex="-1">统计数据怎么来的 <a class="header-anchor" href="#统计数据怎么来的" aria-label="Permalink to &quot;统计数据怎么来的&quot;">​</a></h2><p>前面我们提到内核是以采样的方式来统计 cpu 使用率的。这个采样周期依赖的是 Linux 时间子系统中的定时器。</p><p>Linux 内核每隔固定周期会发出 timer interrupt (IRQ 0)，这有点像乐谱中的节拍的概念。每隔一段时间，就打出一个拍子，Linux 就响应之并处理一些事情。</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwqH85vreK5IDjV8DfNTUBfBakoDoNlRZQXW5morqWDu4Kib7M0o03o0L0v8eNWmWeplBmn64WGaI7A/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>一个节拍的长度是多长时间，是通过 CONFIG_HZ 来定义的。它定义的方式是每一秒有几次 timer interrupts。不同的系统中这个节拍的大小可能不同，通常在 1 ms 到 10 ms 之间。可以在自己的 Linux config 文件中找到它的配置。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;"># grep ^CONFIG_HZ /boot/config-5.4.56.bsk.10-amd64</span></span>
<span class="line"><span style="color:#A6ACCD;">CONFIG_HZ=1000</span></span></code></pre></div><p>从上述结果中可以看出，我的机器每秒要打出 1000 次节拍。也就是每 1 ms 一次。</p><p>每次当时间中断到来的时候，都会调用 update_process_times 来更新系统时间。更新后的时间都存储在我们前面提到的 percpu 变量 kcpustat_cpu 中。</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwqH85vreK5IDjV8DfNTUBfBiaiam2nPqwT9BeHxibXdDxIS7dhSwhTtQluE9JxHKuT6nTz2CujOZX5Dw/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>我们来详细看下汇总过程 update_process_times 的源码，它位于 kernel/time/timer.c 文件中。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">//file:kernel/time/timer.c</span></span>
<span class="line"><span style="color:#A6ACCD;">void update_process_times(int user_tick)</span></span>
<span class="line"><span style="color:#A6ACCD;">{</span></span>
<span class="line"><span style="color:#A6ACCD;"> struct task_struct *p = current;</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;"> //进行时间累积处理</span></span>
<span class="line"><span style="color:#A6ACCD;"> account_process_tick(p, user_tick);</span></span>
<span class="line"><span style="color:#A6ACCD;"> ...</span></span>
<span class="line"><span style="color:#A6ACCD;">}</span></span></code></pre></div><p>这个函数的参数 user_tick 指的是采样的瞬间是处于内核态还是用户态。接下来调用 account_process_tick。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">//file:kernel/sched/cputime.c</span></span>
<span class="line"><span style="color:#A6ACCD;">void account_process_tick(struct task_struct *p, int user_tick)</span></span>
<span class="line"><span style="color:#A6ACCD;">{</span></span>
<span class="line"><span style="color:#A6ACCD;"> cputime = TICK_NSEC;</span></span>
<span class="line"><span style="color:#A6ACCD;"> ...</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;"> if (user_tick)</span></span>
<span class="line"><span style="color:#A6ACCD;">  //3.1 统计用户态时间</span></span>
<span class="line"><span style="color:#A6ACCD;">  account_user_time(p, cputime);</span></span>
<span class="line"><span style="color:#A6ACCD;"> else if ((p != rq-&gt;idle) || (irq_count() != HARDIRQ_OFFSET))</span></span>
<span class="line"><span style="color:#A6ACCD;">  //3.2 统计内核态时间</span></span>
<span class="line"><span style="color:#A6ACCD;">  account_system_time(p, HARDIRQ_OFFSET, cputime);</span></span>
<span class="line"><span style="color:#A6ACCD;"> else</span></span>
<span class="line"><span style="color:#A6ACCD;">  //3.3 统计空闲时间</span></span>
<span class="line"><span style="color:#A6ACCD;">  account_idle_time(cputime);</span></span>
<span class="line"><span style="color:#A6ACCD;">}</span></span></code></pre></div><p>在这个函数中，首先设置 <code>cputime = TICK_NSEC</code>, 一个 TICK_NSEC 的定义是一个节拍所占的纳秒数。接下来根据判断结果分别执行 account_user_time、account_system_time 和 account_idle_time 来统计用户态、内核态和空闲时间。</p><h3 id="用户态时间统计" tabindex="-1">用户态时间统计 <a class="header-anchor" href="#用户态时间统计" aria-label="Permalink to &quot;用户态时间统计&quot;">​</a></h3><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">//file:kernel/sched/cputime.c</span></span>
<span class="line"><span style="color:#A6ACCD;">void account_user_time(struct task_struct *p, u64 cputime)</span></span>
<span class="line"><span style="color:#A6ACCD;">{</span></span>
<span class="line"><span style="color:#A6ACCD;"> //分两种种情况统计用户态 CPU 的使用情况</span></span>
<span class="line"><span style="color:#A6ACCD;"> int index;</span></span>
<span class="line"><span style="color:#A6ACCD;"> index = (task_nice(p) &gt; 0) ? CPUTIME_NICE : CPUTIME_USER;</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;"> //将时间累积到 /proc/stat 中</span></span>
<span class="line"><span style="color:#A6ACCD;"> task_group_account_field(p, index, cputime);</span></span>
<span class="line"><span style="color:#A6ACCD;"> ......</span></span>
<span class="line"><span style="color:#A6ACCD;">}</span></span></code></pre></div><p>account_user_time 函数主要分两种情况统计：</p><ul><li>如果进程的 nice 值大于 0，那么将会增加到 CPU 统计结构的 nice 字段中。</li><li>如果进程的 nice 值小于等于 0，那么增加到 CPU 统计结构的 user 字段中。</li></ul><p>看到这里，开篇的问题 2 就有答案了，其实用户态的时间不只是 user 字段，nice 也是。之所以要把 nice 分出来，是为了让 Linux 用户更一目了然地看到调过 nice 的进程所占的 cpu 周期有多少。</p><p>我们平时如果想要观察系统的用户态消耗的时间的话，应该是将 top 中输出的 user 和 nice 加起来一并考虑，而不是只看 user！</p><p>接着调用 task_group_account_field 来把时间加到前面我们用到的 kernel_cpustat 内核变量中。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">//file:kernel/sched/cputime.c</span></span>
<span class="line"><span style="color:#A6ACCD;">static inline void task_group_account_field(struct task_struct *p, int index,</span></span>
<span class="line"><span style="color:#A6ACCD;">      u64 tmp)</span></span>
<span class="line"><span style="color:#A6ACCD;">{</span></span>
<span class="line"><span style="color:#A6ACCD;"> __this_cpu_add(kernel_cpustat.cpustat[index], tmp);</span></span>
<span class="line"><span style="color:#A6ACCD;"> ...</span></span>
<span class="line"><span style="color:#A6ACCD;">}</span></span></code></pre></div><h3 id="内核态时间统计" tabindex="-1">内核态时间统计 <a class="header-anchor" href="#内核态时间统计" aria-label="Permalink to &quot;内核态时间统计&quot;">​</a></h3><p>我们再来看内核态时间是如何统计的，找到 account_system_time 的代码。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">//file:kernel/sched/cputime.c</span></span>
<span class="line"><span style="color:#A6ACCD;">void account_system_time(struct task_struct *p, int hardirq_offset, u64 cputime)</span></span>
<span class="line"><span style="color:#A6ACCD;">{</span></span>
<span class="line"><span style="color:#A6ACCD;"> if (hardirq_count() - hardirq_offset)</span></span>
<span class="line"><span style="color:#A6ACCD;">  index = CPUTIME_IRQ;</span></span>
<span class="line"><span style="color:#A6ACCD;"> else if (in_serving_softirq())</span></span>
<span class="line"><span style="color:#A6ACCD;">  index = CPUTIME_SOFTIRQ;</span></span>
<span class="line"><span style="color:#A6ACCD;"> else</span></span>
<span class="line"><span style="color:#A6ACCD;">  index = CPUTIME_SYSTEM;</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;"> account_system_index_time(p, cputime, index);</span></span>
<span class="line"><span style="color:#A6ACCD;">}</span></span></code></pre></div><p>内核态的时间主要分 3 种情况进行统计。</p><ul><li>如果当前处于硬中断执行上下文, 那么统计到 irq 字段中；</li><li>如果当前处于软中断执行上下文, 那么统计到 softirq 字段中；</li><li>否则统计到 system 字段中。</li></ul><p>判断好要加到哪个统计项中后，依次调用 account_system_index_time、task_group_account_field 来将这段时间加到内核变量 kernel_cpustat 中。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">//file:kernel/sched/cputime.c</span></span>
<span class="line"><span style="color:#A6ACCD;">static inline void task_group_account_field(struct task_struct *p, int index,</span></span>
<span class="line"><span style="color:#A6ACCD;">      u64 tmp)</span></span>
<span class="line"><span style="color:#A6ACCD;">{ </span></span>
<span class="line"><span style="color:#A6ACCD;"> __this_cpu_add(kernel_cpustat.cpustat[index], tmp);</span></span>
<span class="line"><span style="color:#A6ACCD;">}</span></span></code></pre></div><h3 id="空闲时间的累积" tabindex="-1">空闲时间的累积 <a class="header-anchor" href="#空闲时间的累积" aria-label="Permalink to &quot;空闲时间的累积&quot;">​</a></h3><p>没错，在内核变量 kernel_cpustat 中不仅仅是统计了各种用户态、内核态的使用时间，空闲也一并统计起来了。</p><p>如果在采样的瞬间，cpu 既不在内核态也不在用户态的话，就将当前节拍的时间都累加到 idle 中。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">//file:kernel/sched/cputime.c</span></span>
<span class="line"><span style="color:#A6ACCD;">void account_idle_time(u64 cputime)</span></span>
<span class="line"><span style="color:#A6ACCD;">{</span></span>
<span class="line"><span style="color:#A6ACCD;"> u64 *cpustat = kcpustat_this_cpu-&gt;cpustat;</span></span>
<span class="line"><span style="color:#A6ACCD;"> struct rq *rq = this_rq();</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;"> if (atomic_read(&amp;rq-&gt;nr_iowait) &gt; 0)</span></span>
<span class="line"><span style="color:#A6ACCD;">  cpustat[CPUTIME_IOWAIT] += cputime;</span></span>
<span class="line"><span style="color:#A6ACCD;"> else</span></span>
<span class="line"><span style="color:#A6ACCD;">  cpustat[CPUTIME_IDLE] += cputime;</span></span>
<span class="line"><span style="color:#A6ACCD;">}</span></span></code></pre></div><p>在 cpu 空闲的情况下，进一步判断当前是不是在等待 IO（例如磁盘 IO），如果是的话这段空闲时间会加到 iowait 中，否则就加到 idle 中。从这里，我们可以看到 iowait 其实是 cpu 的空闲时间，只不过是在等待 IO 完成而已。</p><p>看到这里，开篇问题 3 也有非常明确的答案了，io wait 其实是 cpu 在空闲状态的一项统计，只不过这种状态和 idle 的区别是 cpu 是因为等待 io 而空闲。</p><h2 id="总结" tabindex="-1">总结 <a class="header-anchor" href="#总结" aria-label="Permalink to &quot;总结&quot;">​</a></h2><p>本文深入分析了 Linux 统计系统 CPU 利用率的内部原理。全文的内容可以用如下一张图来汇总：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwqH85vreK5IDjV8DfNTUBfB0Zy6wFfI2icK1DDq4CJaWpJA08QDibuXR6mSPib3GxfyAD3yONy9hgHyQ/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>Linux 中的定时器会以某个固定节拍，比如 1 ms 一次采样各个 cpu 核的使用情况，然后将当前节拍的所有时间都累加到 user/nice/system/irq/softirq/io_wait/idle 中的某一项上。</p><p>top 命令是读取的 /proc/stat 中输出的 cpu 各项利用率数据，而这个数据在内核中是根据 kernel_cpustat 来汇总并输出的。</p><p>回到开篇问题 1，top 输出的利用率信息是如何计算出来的，它精确吗？</p><p>/proc/stat 文件输出的是某个时间点的各个指标所占用的节拍数。如果想像 top 那样输出一个百分比，计算过程是分两个时间点 t1, t2 分别获取一下 stat 文件中的相关输出，然后经过个简单的算术运算便可以算出当前的 cpu 利用率。</p><p>再说是否精确。这个统计方法是采样的，只要是采样，肯定就不是百分之百精确。但由于我们查看 cpu 使用率的时候往往都是计算 1 秒甚至更长一段时间的使用情况，这其中会包含很多采样点，所以查看整体情况是问题不大的。</p><p>另外从本文，我们也学到了 top 中输出的 cpu 时间项目其实大致可以分为三类：</p><p>**第一类：**用户态消耗时间，包括 user 和 nice。如果想看用户态的消耗，要将 user 和 nice 加起来看才对。 **第二类：**内核态消耗时间，包括 irq、softirq 和 system。 **第三类：**空闲时间，包括 io_wait 和 idle。其中 io_wait 也是 cpu 的空闲状态，只不过是在等 io 完成而已。如果只是想看 cpu 到底有多闲，应该把 io_wait 和 idle 加起来才对。</p><h1 id="linux系统负载" tabindex="-1">Linux系统负载 <a class="header-anchor" href="#linux系统负载" aria-label="Permalink to &quot;Linux系统负载&quot;">​</a></h1><p>今天，我们来聊聊linux负载相关的参数和问题。我们经常会使用 <code>top</code> 命令来查看系统的性能情况，在 <code>top</code> 命令的第一行可以看到 <code>load average</code> 这个数据，如下图所示：</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202302271535882.png" alt="image-20230227153551772" style="zoom:67%;"><p><code>load average</code> 包含 3 列，分别表示 1 分钟、5 分钟和 15 分钟的 <code>系统平均负载</code>。</p><p>对于系统平均负载这个数值，可能很多同学并不完全理解其意义，并不知道数值达到多少时才表示系统负载过高。本文将会以简单的语言来介绍系统平均负载这个概念，并且会介绍 Linux 内核是怎么计算这个数值。</p><h2 id="系统平均负载" tabindex="-1">系统平均负载 <a class="header-anchor" href="#系统平均负载" aria-label="Permalink to &quot;系统平均负载&quot;">​</a></h2><blockquote><p>《Understanding Linux CPU Load》这篇文章已经非常通俗的解释了什么是 <code>系统平均负载</code>，借用一下此文中例子</p></blockquote><blockquote><p>如果将 CPU 比作是桥梁，对于单核的 CPU 就好比是单车道的桥梁。每次桥梁只能让一辆汽车通过，并且要以规定的速度通过。那么：</p></blockquote><blockquote><p>如果每个时刻都只有一辆汽车通过，那么所有汽车都不用排队，此时桥梁的使用率最高。以平均负载 1.0 表示，如下图所示：</p></blockquote><p><img src="https://mmbiz.qpic.cn/mmbiz_png/ciab8jTiab9J4s2b0yp6lH4YeiaFic9em4M9ssumcQLibIwYiachgAedqn0cMtjqMAv2ZzI1lwS2ibA6foPsJLicVicZhLg/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><blockquote><p>如果每隔一段时间才有一辆汽车通过，那么表示桥梁部分时间处于空闲的情况。并且间隔的时间越长，表示桥梁空闲率越高。此时的平均负载小于 1.0，如下图所示：</p></blockquote><p><img src="https://mmbiz.qpic.cn/mmbiz_png/ciab8jTiab9J4s2b0yp6lH4YeiaFic9em4M9h7j3shQibHvHB7fGPTFmL9EKp8URZbnZicoK6icEiafBnVsvuFeof2JWdQ/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><blockquote><p>当有大量的汽车通过桥梁时，有些汽车需要等待其他车辆通过后才能继续通行，这时表示桥梁超负荷工作。此时平均负载大于1.0，如下图所示：</p></blockquote><p><img src="https://mmbiz.qpic.cn/mmbiz_png/ciab8jTiab9J4s2b0yp6lH4YeiaFic9em4M9hdRKCxMjwf8aa2GXD7ctpz6ibJs5TblR6FlttawNBEfmLA6E7LJfLxw/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>系统的平均负载与上面的例子一样，在单核 CPU 的环境下：</p><blockquote><ul><li>当平均负载等于 1.0 时，表示 CPU 使用率最高。</li><li>当平均负载小于 1.0 时，表示 CPU 使用率处于空闲状态。</li><li>当平均负载大于 1.0 时，表示 CPU 使用率已经超过负荷。</li></ul></blockquote><p>对于单核 CPU 来说，平均负载 1.0 表示使用率最高。但对于多核 CPU 来说，平均负载要乘以核心数。比如在 4 核 CPU 的系统中，当平均负载为 4.0 时，才表示 CPU 的使用率最高。</p><h2 id="linux-平均负载计算原理" tabindex="-1">Linux 平均负载计算原理 <a class="header-anchor" href="#linux-平均负载计算原理" aria-label="Permalink to &quot;Linux 平均负载计算原理&quot;">​</a></h2><p>在介绍系统平均负载的计算原理前，先要介绍一下什么是系统负载。在 Linux 系统中，系统负载表示 <strong>系统中当前正在运行的进程数量</strong>，其包括 <code>可运行状态</code> 的进程数和 <code>不可中断休眠状态</code> 的进程数的和。注意：不可中断休眠状态的进程一般是在等待 I/O 完成的进程。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">系统负载 = 可运行状态进程数 + 不可中断休眠状态进程数</span></span></code></pre></div><p>知道了什么是 <code>系统负载</code>，那么 <code>系统平均负载</code> 就容易理解了。比如每 5 秒统计一次系统负载，1 分钟内会统计 12 次。如下所示：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">第5秒  -&gt; 系统负载</span></span>
<span class="line"><span style="color:#A6ACCD;">第10秒 -&gt; 系统负载</span></span>
<span class="line"><span style="color:#A6ACCD;">第15秒 -&gt; 系统负载</span></span>
<span class="line"><span style="color:#A6ACCD;">...</span></span>
<span class="line"><span style="color:#A6ACCD;">第60秒 -&gt; 系统负载</span></span></code></pre></div><p>然后把每次统计到的系统负载加起来，再除以统计次数，即可得出 <code>系统平均负载</code>。如下图所示：</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/ciab8jTiab9J4s2b0yp6lH4YeiaFic9em4M9q6EoibS28TZqgSjxoZ03W3bklThxV8RpE7gicCsKFO8uTqPjnDwheLaA/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>但这种计算方式有些缺陷，就是预测系统负载的准确性不够高，因为越老的数据越不能反映现在的情况。打个比方，要预测某条公路今天的车流量，使用昨天的数据作为预测依据，会比使用一个月之前的数据作为依据要准确得多。</p><p><strong>所以，时间越近的数据，对未来的预测准确性越高。</strong></p><p>Linux 内核使用一种名为 <code>指数平滑法</code> 的算法来解决这个问题，指数平滑法的核心思想是对新老数据进行加权，越老的数据权重越低。</p><blockquote><p>指数平滑法：是由 Robert G..Brown 提出的一种加权移动平均法，有兴趣了解其数学原理的可以搜索相关资料，本文不作详细介绍。</p></blockquote><p>其计算公式如下（来源于 Linux 内核代码 kernel/sched/core.c）：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">load1 = load0 * e + active * (1 - e)</span></span></code></pre></div><p>解释一下上面公式的意思：</p><ul><li><strong>load1</strong>：表示时间 t + 1 的系统负载。</li><li><strong>load0</strong>：表示时间 t 的系统负载。</li><li><strong>e</strong>：表示衰减系数。</li><li><strong>active</strong>：表示系统中的活跃进程数（可运行状态进程数 + 不可中断休眠状态进程数）。</li></ul><p>所以，我们就可以使用上面的公式来预测任何时间的系统平均负载了。比如，我们要预测时间点 n 的系统平均负载，那么可以这样来计算：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">load1 = load0 * e + active * (1 - e)</span></span>
<span class="line"><span style="color:#A6ACCD;">load2 = load1 * e + active * (1 - e)</span></span>
<span class="line"><span style="color:#A6ACCD;">load3 = load2 * e + active * (1 - e)</span></span>
<span class="line"><span style="color:#A6ACCD;">...</span></span>
<span class="line"><span style="color:#A6ACCD;">loadn = loadn-1 * e + active * (1 - e)</span></span></code></pre></div><p>现在就只剩下 <code>衰减系数</code> 该如何计算了。</p><p>从 Linux 内核的注释可以了解到，计算 1 分钟内系统平均负载的 <code>衰减系数</code> 的计算方式如下：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">1 / exp(5sec / 1min)</span></span></code></pre></div><p>其中：</p><ul><li><strong>5sec</strong>：表示统计的时间间隔，5秒。</li><li><strong>1min</strong>：表示统计的时长，1分钟。</li><li><strong>exp</strong>：表示以自然常数 e 为底的指数函数。</li></ul><p>也就是说，要计算一分钟的系统平均负载时，需要使用上面的 <code>衰减系数</code>。对于 5 分钟和 15 分钟的 <code>衰减系数</code> 的计算方式分别为：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">1 / exp(5sec / 5min)</span></span>
<span class="line"><span style="color:#A6ACCD;">1 / exp(5sec / 15min)</span></span></code></pre></div><p>Linux 内核已经把 1 分钟、5 分钟和 15 分钟的 <code>衰减系数</code> 结果计算出来，并且定义在 <code>include/linux/sched.h</code> 文件中，如下所示：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">#define EXP_1       1884        /* 1/exp(5sec/1min) as fixed-point */</span></span>
<span class="line"><span style="color:#A6ACCD;">#define EXP_5       2014        /* 1/exp(5sec/5min) */</span></span>
<span class="line"><span style="color:#A6ACCD;">#define EXP_15      2037        /* 1/exp(5sec/15min) */</span></span></code></pre></div><p>通过上述公式计算出来的 <code>衰减系数</code> 是个浮点数，而在内核中是不能进行浮点数运行的。解决方法是先对 <code>衰减系数</code> 进行扩大，然后在展示时最缩小。所以，上面的 <code>衰减系数</code> 数值是经过扩大 2048 倍后的结果。</p><h2 id="linux-平均负载计算实现" tabindex="-1">Linux 平均负载计算实现 <a class="header-anchor" href="#linux-平均负载计算实现" aria-label="Permalink to &quot;Linux 平均负载计算实现&quot;">​</a></h2><p><strong>万事俱备，只欠东风</strong>。上面我们已经把所有的知识点介绍了，现在来分析一下 Linux 内核代码是怎样实现的。</p><h3 id="_1-数据存储" tabindex="-1">1. 数据存储 <a class="header-anchor" href="#_1-数据存储" aria-label="Permalink to &quot;1. 数据存储&quot;">​</a></h3><p>在 Linux 内核中，使用了 <code>avenrun</code> 数组来存储 1 分钟、5 分钟和 15 分钟的系统平均负载，如下代码所示：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">unsigned long avenrun[3];</span></span></code></pre></div><p>如元素 <code>avenrun[0]</code> 用于存储 1 分钟内的系统平均负载，而元素 <code>avenrun[1]</code> 用于存储 5 分钟的系统平均负载，如此类推。</p><h3 id="_2-统计过程" tabindex="-1">2. 统计过程 <a class="header-anchor" href="#_2-统计过程" aria-label="Permalink to &quot;2. 统计过程&quot;">​</a></h3><p>由于统计需要定时进行，所以内核把统计过程放置到 <code>时钟中断</code> 中进行。当 <code>时钟中断</code> 触发时，将会调用 <code>do_timer()</code> 函数，而 <code>do_timer()</code> 函数将会调用 <code>calc_global_load()</code> 来统计系统平均负载。</p><p>我们来看看 <code>calc_global_load()</code> 函数的实现：</p><div class="language-c"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">void</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">calc_global_load</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">unsigned</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">long</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">ticks</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">long</span><span style="color:#F07178;"> active</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> delta</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 1. 如果还没到统计的时间间隔，那么将不进行统计（5秒统计一次）</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">(</span><span style="color:#82AAFF;">time_before</span><span style="color:#89DDFF;">(</span><span style="color:#F07178;">jiffies</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> calc_load_update </span><span style="color:#89DDFF;">+</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">10</span><span style="color:#89DDFF;">))</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 2. 获取活跃进程数</span></span>
<span class="line"><span style="color:#F07178;">    delta </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">calc_load_fold_idle</span><span style="color:#89DDFF;">();</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">(</span><span style="color:#F07178;">delta</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#82AAFF;">atomic_long_add</span><span style="color:#89DDFF;">(</span><span style="color:#F07178;">delta</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;</span><span style="color:#F07178;">calc_load_tasks</span><span style="color:#89DDFF;">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">    active </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">atomic_long_read</span><span style="color:#89DDFF;">(&amp;</span><span style="color:#F07178;">calc_load_tasks</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#F07178;">    active </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> active </span><span style="color:#89DDFF;">&gt;</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">0</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">?</span><span style="color:#F07178;"> active </span><span style="color:#89DDFF;">*</span><span style="color:#F07178;"> FIXED_1 </span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 3. 统计各个时间段系统平均负载</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">avenrun</span><span style="color:#89DDFF;">[</span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">]</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">calc_load</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">avenrun</span><span style="color:#89DDFF;">[</span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">],</span><span style="color:#F07178;"> EXP_1</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> active</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">avenrun</span><span style="color:#89DDFF;">[</span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">]</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">calc_load</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">avenrun</span><span style="color:#89DDFF;">[</span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">],</span><span style="color:#F07178;"> EXP_5</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> active</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">avenrun</span><span style="color:#89DDFF;">[</span><span style="color:#F78C6C;">2</span><span style="color:#89DDFF;">]</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">calc_load</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">avenrun</span><span style="color:#89DDFF;">[</span><span style="color:#F78C6C;">2</span><span style="color:#89DDFF;">],</span><span style="color:#F07178;"> EXP_15</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> active</span><span style="color:#89DDFF;">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;font-style:italic;">// 4. 更新下次统计的时间（增加5秒）</span></span>
<span class="line"><span style="color:#F07178;">    calc_load_update </span><span style="color:#89DDFF;">+=</span><span style="color:#F07178;"> LOAD_FREQ</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">    ...</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><p><code>calc_global_load()</code> 函数主要完成 4 件事情：</p><ol><li>判断当前时间是否需要进行统计，如果还没到统计的时间间隔，那么将不进行统计（5秒统计一次）。</li><li>获取活跃进程数（可运行状态进程数 + 不可中断休眠状态进程数）。</li><li>统计各个时间段系统平均负载（1分钟、5分钟和15分钟）。</li><li>更新下次统计的时间（增加5秒）。</li></ol><p>从上面的分析可知，<code>calc_global_load()</code> 函数将会调用 <code>calc_load()</code> 来计算系统平均负载。其代码如下：</p><div class="language-c"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">/*</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"> * a1 = a0 * e + a * (1 - e)</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"> */</span></span>
<span class="line"><span style="color:#C792EA;">static</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">unsigned</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">long</span></span>
<span class="line"><span style="color:#82AAFF;">calc_load</span><span style="color:#89DDFF;">(</span><span style="color:#C792EA;">unsigned</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">long</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">load</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">unsigned</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">long</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">exp</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">unsigned</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">long</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">active</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    load </span><span style="color:#89DDFF;">*=</span><span style="color:#F07178;"> exp</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    load </span><span style="color:#89DDFF;">+=</span><span style="color:#F07178;"> active </span><span style="color:#89DDFF;">*</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">(</span><span style="color:#F07178;">FIXED_1 </span><span style="color:#89DDFF;">-</span><span style="color:#F07178;"> exp</span><span style="color:#89DDFF;">);</span></span>
<span class="line"><span style="color:#F07178;">    load </span><span style="color:#89DDFF;">+=</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">1UL</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&lt;&lt;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">(</span><span style="color:#F07178;">FSHIFT </span><span style="color:#89DDFF;">-</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> load </span><span style="color:#89DDFF;">&gt;&gt;</span><span style="color:#F07178;"> FSHIFT</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><p><code>calc_load()</code> 函数的各个参数意义如下：</p><ul><li><strong>load</strong>：<code>t-1</code> 时间点的系统负载。</li><li><strong>exp</strong>：衰减系数。</li><li><strong>active</strong>：活跃进程数。</li></ul><p>可以看出，<code>calc_load()</code> 函数的实现就是按照 <code>指数平滑法</code> 来计算的。</p><h2 id="负载命令⭐" tabindex="-1">负载命令⭐ <a class="header-anchor" href="#负载命令⭐" aria-label="Permalink to &quot;负载命令⭐&quot;">​</a></h2><p><a href="https://blog.csdn.net/junboliang/article/details/105819798" target="_blank" rel="noreferrer">https://blog.csdn.net/junboliang/article/details/105819798</a></p><p><a href="https://zhuanlan.zhihu.com/p/60066607" target="_blank" rel="noreferrer">https://zhuanlan.zhihu.com/p/60066607</a></p><h3 id="stress" tabindex="-1">stress <a class="header-anchor" href="#stress" aria-label="Permalink to &quot;stress&quot;">​</a></h3><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#FFCB6B;">sudo</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">epel-release</span></span>
<span class="line"><span style="color:#FFCB6B;">sudo</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">update</span></span>
<span class="line"><span style="color:#FFCB6B;">sudo</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">stress</span></span></code></pre></div><p>模拟CPU负载：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">stress --cpu 4 --timeout 60s</span></span></code></pre></div><p>这会模拟4个CPU核心的负载，在60秒后停止。</p><p>模拟内存负载：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">stress --vm 1 --vm-bytes 512M --timeout 60s</span></span></code></pre></div><p>这会模拟使用512MB内存的虚拟机，持续60秒。</p><p>模拟IO负载：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">stress --io 4 --timeout 60s</span></span></code></pre></div><p>这会模拟4个IO操作，在60秒后停止。</p><p>模拟磁盘负载：</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">stress --hdd 1 --hdd-bytes 1G --timeout 60s</span></span></code></pre></div><p>这会模拟写入1GB数据的磁盘操作，在60秒后停止。</p><h3 id="lookbusy" tabindex="-1">lookbusy <a class="header-anchor" href="#lookbusy" aria-label="Permalink to &quot;lookbusy&quot;">​</a></h3><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;"># 下载编译安装lookbusy</span></span>
<span class="line"><span style="color:#FFCB6B;">wget</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">http://www.devin.com/lookbusy/download/lookbusy-1.4.tar.gz</span></span>
<span class="line"><span style="color:#FFCB6B;">tar</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-xzf</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">lookbusy-1.4.tar.gz</span></span>
<span class="line"><span style="color:#82AAFF;">cd</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">lookbusy-1.4</span></span>
<span class="line"><span style="color:#FFCB6B;">./configure</span></span>
<span class="line"><span style="color:#FFCB6B;">make</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&amp;</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">make</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span></span></code></pre></div><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;"># 所有的cpu使用率都是30%</span></span>
<span class="line"><span style="color:#FFCB6B;">lookbusy</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-c</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">30</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 占用所有 CPU 核心各 70%</span></span>
<span class="line"><span style="color:#FFCB6B;">lookbusy</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-c</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">70</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 占用两个 CPU 核心各 70%</span></span>
<span class="line"><span style="color:#FFCB6B;">lookbusy</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-c</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">70</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-n</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 占用所有 CPU 核心在 60%-70% 上下浮动</span></span>
<span class="line"><span style="color:#FFCB6B;">lookbusy</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-c</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">60</span><span style="color:#C3E88D;">-70</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-r</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">curve</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># cpu以60分钟为周期，30分钟是峰值，使用率在60%-70%上下浮动</span></span>
<span class="line"><span style="color:#FFCB6B;">lookbusy</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-c</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">60</span><span style="color:#C3E88D;">-70</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--cpu-mode</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">curve</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--cpu-curve-period</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">60</span><span style="color:#C3E88D;">m</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--cpu-curve-peak</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">30</span><span style="color:#C3E88D;">m</span></span></code></pre></div><h3 id="sysbench" tabindex="-1">sysbench <a class="header-anchor" href="#sysbench" aria-label="Permalink to &quot;sysbench&quot;">​</a></h3><p><a href="https://github.com/akopytov/sysbench" target="_blank" rel="noreferrer">akopytov/sysbench：可编写脚本的数据库和系统性能基准测试 (github.com)</a></p><h4 id="快速安装" tabindex="-1">快速安装 <a class="header-anchor" href="#快速安装" aria-label="Permalink to &quot;快速安装&quot;">​</a></h4><p>Debian/Ubuntu</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.deb.sh | sudo bash</span></span>
<span class="line"><span style="color:#A6ACCD;">sudo apt -y install sysbench</span></span></code></pre></div><p>RHEL/CentOS:</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash</span></span>
<span class="line"><span style="color:#A6ACCD;">sudo yum -y install sysbench</span></span></code></pre></div><h4 id="测试概览" tabindex="-1">测试概览 <a class="header-anchor" href="#测试概览" aria-label="Permalink to &quot;测试概览&quot;">​</a></h4><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#FFCB6B;">sysbench</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--help</span></span>
<span class="line"><span style="color:#FFCB6B;">sysbench</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--test=cpu</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">help</span></span>
<span class="line"><span style="color:#FFCB6B;">sysbench</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--test=fileio</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">help</span></span>
<span class="line"><span style="color:#FFCB6B;">sysbench</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--test=memory</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">help</span></span>
<span class="line"><span style="color:#FFCB6B;">sysbench</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">threads</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">help</span></span></code></pre></div><h4 id="测试cpu" tabindex="-1">测试CPU <a class="header-anchor" href="#测试cpu" aria-label="Permalink to &quot;测试CPU&quot;">​</a></h4><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">sysbench cpu --cpu-max-prime=20000 --threads=2 run</span></span></code></pre></div><h4 id="测试磁盘io" tabindex="-1">测试磁盘IO <a class="header-anchor" href="#测试磁盘io" aria-label="Permalink to &quot;测试磁盘IO&quot;">​</a></h4><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#FFCB6B;">sysbench</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--test=fileio</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--file-total-size=2G</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">prepare</span></span></code></pre></div><h4 id="测试mysql数据库" tabindex="-1">测试MySQL数据库 <a class="header-anchor" href="#测试mysql数据库" aria-label="Permalink to &quot;测试MySQL数据库&quot;">​</a></h4><p>准备测试数据：Sysbench需要一些测试数据来执行基准测试。你可以使用Sysbench提供的脚本生成测试数据。以下命令将生成4个包含10000行数据的表：执行完成就看到mysql中生成了对应表</p><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;"># 重要参数：--mysql-db指定数据库，--table-size=10000每张表生成1万条数据</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 重要参数：--tables=4生成4张表，--threads=20，20个线程并发执行</span></span>
<span class="line"><span style="color:#FFCB6B;">sysbench</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">oltp_read_write</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--mysql-host=127.0.0.1</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--mysql-port=3306</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--mysql-user=root</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--mysql-password=123456</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--mysql-db=xuexi</span><span style="color:#A6ACCD;">  </span><span style="color:#C3E88D;">--table-size=10000</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--tables=4</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--threads=20</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">prepare</span></span></code></pre></div><p>执行基准测试：执行以下命令来运行基准测试：</p><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;"># 重要参数：--threads=20，线程数，--time=10持续时间10s，--report-interval=3，3秒输出一次报告</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># --percentile=99,在99%的情况下系统的性能水平</span></span>
<span class="line"><span style="color:#FFCB6B;">sysbench</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">oltp_read_write</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--mysql-host=127.0.0.1</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--mysql-port=3306</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--mysql-user=root</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--mysql-password=123456</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--mysql-db=xuexi</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--table-size=10000</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--tables=4</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--threads=20</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--report-interval=3</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--time=10</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--percentile=99</span><span style="color:#A6ACCD;">  </span><span style="color:#C3E88D;">run</span></span></code></pre></div><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202304291950602.png" alt="image-20230429195008464" style="zoom:80%;"><p>清理测试数据：完成测试后，可以使用以下命令清理测试数据：</p><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#FFCB6B;">sysbench</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">oltp_read_write</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--mysql-host=127.0.0.1</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--mysql-port=3306</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--mysql-user=root</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--mysql-password=123456</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--mysql-db=xuexi</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--table-size=10000</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--tables=4</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--threads=10</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">cleanup</span></span></code></pre></div><h1 id="服务器优化⭐⭐" tabindex="-1">服务器优化⭐⭐ <a class="header-anchor" href="#服务器优化⭐⭐" aria-label="Permalink to &quot;服务器优化⭐⭐&quot;">​</a></h1><p>听多了架构优化，数据库优化，今天我们来聊聊服务器优化。</p><p>我们开发的软件服务需要在服务器上运行，所以服务器性能代表了软件的性能上限，因此服务器性能调优是个十分重要的环节，然而大部分同学对服务器性能调优关注的较少，今天从3个部分对服务器性能调优进行介绍，分别是：服务器配置选择，服务器负载分析，服务器内核参数调优。</p><h2 id="服务器配置选择" tabindex="-1">服务器配置选择 <a class="header-anchor" href="#服务器配置选择" aria-label="Permalink to &quot;服务器配置选择&quot;">​</a></h2><p>服务器一般是由CPU、内存、磁盘和网卡组成，因此选择服务器配置就是选择CPU核数、内存大小、磁盘大小及类型、网络带宽。但是，服务器配置的选择是很难标准化的，也就是说很难推断出“一台需要达到1000TPS的后端服务器”的配置应该是什么样的。因为软件的最终运行性能与软件的实现方式是紧密相关的，即使是同一个后端应用程序中的两个接口，由于具体功能的差别，性能也会有所差别。</p><p>因此，服务器配置的选择应该基于具体的测试结果。一开始可以选用配置较低的服务器做调优和测试，并以该服务器的测试结果作为选择服务器的依据。</p><blockquote><p>以一个订单业务为例，经过测试后，一台配置为4核 CPU 、16GB内存、10Mbps带宽、50GB机械磁盘的服务器的测试结果为：支持50并发量和300TPS吞吐量（增大并发量后会出现超时报错）。而在压力测试过程中， CPU 的使用率接近75%，内存使用率在 50％以下，带宽使用率在50％以下，除去日志以外无磁盘操作。</p></blockquote><p>因此可以认为，一台配置为4核 CPU ( CPU 使用率需要在75％以下）、8GB内存（内存使用率可以接近100%)、 5Mbps 带宽（带宽使用率可以接近100%）的服务器，可以满足订单接口支持50并发量、300TPS吞吐量的压力。</p><blockquote><p>如果需要达到200并发数、2400TPS吞吐量的目标的话，则需要8台配置为4核 CPU 、8GB内存、5Mbps带宽的服务器，或者1台配置为32核 CPU 、64GB内存、40Mbps带宽的服务器。当然，最终的服务器配置还是需要通过测试来验证。</p></blockquote><blockquote><p>注意：在以上订单接口的例子中，后端服务器和数据库等服务器需要一起调试，避免后端服务器性能过剩，而数据库等服务器性能不足的情况发生。另外，以上选择服务器配置的方法不一定适用于所有场景，请斟酌参考。</p></blockquote><h2 id="服务器内核参数调优" tabindex="-1">服务器内核参数调优 <a class="header-anchor" href="#服务器内核参数调优" aria-label="Permalink to &quot;服务器内核参数调优&quot;">​</a></h2><p>光有强大的物理性能是不够的，还需要对内核参数进行调优，这样才能在高并发压力下充分体现服务器应有的性能。当然，并不是所有的服务器都需要做高并发性能调优，一般来说，只需要对要处理高并发请求的服务器进行内核参数调优即可，常见的包括：前端服务器，后端服务器，数据库服务器。</p><p>服务器常见的调优参数主要有两个：单个进程最大打开文件数 和 TCP相关设置。</p><h3 id="单个进程最大打开文件数" tabindex="-1">单个进程最大打开文件数 <a class="header-anchor" href="#单个进程最大打开文件数" aria-label="Permalink to &quot;单个进程最大打开文件数&quot;">​</a></h3><p>修改单个文件最大打开文件数，只需要编辑<code>/etc/security/limits.conf</code>文件，在文件末尾加上以下四句</p><div class="language-apl"><button title="Copy Code" class="copy"></button><span class="lang">apl</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> soft	nofile	</span><span style="color:#F78C6C;">65535</span></span>
<span class="line"><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> hard	nofile	</span><span style="color:#F78C6C;">65535</span></span>
<span class="line"><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> soft	nproc	</span><span style="color:#F78C6C;">65535</span></span>
<span class="line"><span style="color:#89DDFF;">*</span><span style="color:#A6ACCD;"> hard	nproc	</span><span style="color:#F78C6C;">65535</span></span></code></pre></div><p>其中<code>*</code> 代表所有用户，65536代表修改的值，重启后生效。</p><h3 id="tcp相关设置" tabindex="-1">TCP相关设置 <a class="header-anchor" href="#tcp相关设置" aria-label="Permalink to &quot;TCP相关设置&quot;">​</a></h3><p>修改TCP相关参数，可以优化TCP高并发通信，编辑<code>/etc/sysctl.conf</code>文件，添加以下内容</p><div class="language-apl"><button title="Copy Code" class="copy"></button><span class="lang">apl</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;"> 为防止洪水攻击，高并发系统需要将此项关闭</span></span>
<span class="line"><span style="color:#A6ACCD;">net</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">ipv4</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">tcp_syncookies </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;"> 开启TCP连接重用，允许处理TIME</span><span style="color:#89DDFF;">-</span><span style="color:#A6ACCD;">WAIT状态的连接重新用于新的TCP连接</span></span>
<span class="line"><span style="color:#A6ACCD;">net</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">ipv4</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">tcp_tw_reuse </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;"> 开启快速回收TCP连接中处于TIME</span><span style="color:#89DDFF;">-</span><span style="color:#A6ACCD;">WAIT状态的连接</span></span>
<span class="line"><span style="color:#A6ACCD;">net</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">ipv4</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">tcp_tw_recycle </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;"> 修改超时时间（ s )，该值表示如果连接由本端关闭，则连接处于 FIN</span><span style="color:#89DDFF;">-</span><span style="color:#A6ACCD;">WAIT</span><span style="color:#89DDFF;">-</span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">状态的时间为 </span></span>
<span class="line"><span style="color:#A6ACCD;">net</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">ipv4</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">tcp_fin_timeout </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">30</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;"> 当 keepalive（长连接）启用的时候，TCP发送 keepalive 消息（探测包）的时间间隔（ s )</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">默认为</span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">个小时</span></span>
<span class="line"><span style="color:#A6ACCD;">net</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">ipv4</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">tcp_keepalive_time </span><span style="color:#89DDFF;">=</span><span style="color:#F78C6C;">1200</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;"> 服务器对外连接的端口范围，影响该服务器与其他服务器的连接数</span></span>
<span class="line"><span style="color:#A6ACCD;">net</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">ipv4</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">ip_local_port_range </span><span style="color:#89DDFF;">=</span><span style="color:#F78C6C;">102465535</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;"> SYN队列的长度，可以容纳更多等待连接的网络连接数，默认为</span><span style="color:#F78C6C;">1024</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">net</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">ipv4</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">tcp_max_syn_backlog </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">65535</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">保持 TIME_WAIT 状态连接的最大数量，如果超过此值，TIME_WAIT 将立刻被清除并打印警告信息，默认为</span><span style="color:#F78C6C;">180000</span></span>
<span class="line"><span style="color:#A6ACCD;">net</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">ipv4</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">tcp_max_tw_buckets </span><span style="color:#89DDFF;">=</span><span style="color:#F78C6C;">5000</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;"> 每个网络接口接收数据包的速率比内核处理这些包的速率快时，允许送到队列的数据包的最大数目</span></span>
<span class="line"><span style="color:#A6ACCD;">net</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">core</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">netdev_max_backlog </span><span style="color:#89DDFF;">=</span><span style="color:#F78C6C;">65535</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;"> TCP最大连接数</span></span>
<span class="line"><span style="color:#A6ACCD;">net</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">core</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">somaxconn </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">65535</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;"> 预留用于接收缓冲的内存默认值（字节） </span></span>
<span class="line"><span style="color:#A6ACCD;">net</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">core</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">rmem_default </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">8388608</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;"> 预留用于接收缓冲的内存最大值（字节） </span></span>
<span class="line"><span style="color:#A6ACCD;">net</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">core</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">rmem_max </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">16777216</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;"> 预留用于发送缓冲的内存默认值（字节） </span></span>
<span class="line"><span style="color:#A6ACCD;">net</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">core</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">wmem_default </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">8388608</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;"> 预留用于发送缓冲的内存最大值（字节） </span></span>
<span class="line"><span style="color:#A6ACCD;">net</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">core</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">wmem_maX </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">16777216</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;"> 避免时间戳异常</span></span>
<span class="line"><span style="color:#A6ACCD;">net</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">ipv4</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">tcp_timestamps </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;"> 系统中最多有多少个 TCP 套接字不被关联到任何一个用户文件句柄上，如果超过这个数字，连接将即刻被复位并打印警告信息，这个限制仅仅是为了防止简单的DoS 攻击</span></span>
<span class="line"><span style="color:#A6ACCD;">net</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">ipv4</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">tcp_max_orphans </span><span style="color:#89DDFF;">=</span><span style="color:#F78C6C;">3276800</span></span></code></pre></div><h2 id="linux服务端最大并发数-1" tabindex="-1">Linux服务端最大并发数 <a class="header-anchor" href="#linux服务端最大并发数-1" aria-label="Permalink to &quot;Linux服务端最大并发数&quot;">​</a></h2><p>在开始今天的文章之前，先抛一个面试题出来：</p><blockquote><p>你接触过的单机最大并发数是多少？ 你认为当前正常配置的服务器物理机最大并发数可以到多少？ 说说你的理解和分析。</p></blockquote><p>思考几分钟，如果你可以<strong>有理有据地说出答案</strong>，那确实就不用再往下看了，关上手机去陪陪家人是个不错的选择。</p><p>思考几分钟，如果你<strong>没有头绪或者对答案不确定</strong>，那么你先不用着急关闭页面去玩耍，你应该继续往下看，因为这个问题很不错。</p><p>对于后端开发人员来说，并发数往往和技术难度是呈正相关的，实际上也确实如此：<strong>体量决定架构</strong>。</p><p>服务端根据不同业务场景会有不同的侧重点，单纯追求高并发其实并不是根本目的，<strong>高可用&amp;稳定性更重要</strong>。</p><p>所以最终我们的目的是：<strong>保证高可用高稳定的基础上追求高并发，降本增效</strong>。</p><p>高可用&amp;高并发是我们直观感受到的，本质上这是个<strong>复杂的系统工程</strong>，每个环节都会影响结果，每一块都值得研究和深入。</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208281002645.png" alt="image-20220828100200547" style="zoom:67%;"><h2 id="_2-c10k问题和c10m问题" tabindex="-1">2. C10K问题和C10M问题 <a class="header-anchor" href="#_2-c10k问题和c10m问题" aria-label="Permalink to &quot;2. C10K问题和C10M问题&quot;">​</a></h2><p>在2000年初的时候，全球互联网的规模并不大，但是当时就已经提出了C10K问题，所谓<strong>C10K就是单机1w并发问题</strong>，虽然现在不觉得是个难题了，但是这在当初是很有远见和挑战的问题。</p><p>C10K问题最早由<strong>Dan Kegel</strong>发布于其个人站点，原文链接如下:</p><blockquote><p><strong><a href="http://www.kegel.com/c10k.html" target="_blank" rel="noreferrer">http://www.kegel.com/c10k.html</a></strong></p></blockquote><p>相关资料显示Dan Kegel目前工作于<strong>Google</strong>，从1978年起开始接触计算机编程，是Winetricks和Crosstool的作者，大佬年轻时的照片：</p><p>Dan Kegel这篇文章阅读难度并不大，大白建议从事服务端开发或者对高性能网络开发有兴趣的读者尝试读一读。</p><p>在APUE第三版都没有提到epoll，所以<strong>我们解决C10K问题的时间并不长</strong>，其中IO复用epoll/kqueue/iocp等技术对于C10k问题的解决起到了非常重要的作用。</p><p>开源大神们基于epoll/kqueue等开发了诸如libevent/libuv等网络库，从而大幅提高了高并发网络的开发效率，对于C/C++程序员来说并不陌生。</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208281003952.png" alt="image-20220828100310866" style="zoom:80%;"><p>这里简单提一下针对下一个10年的展望和挑战：<strong>C10M问题</strong>。</p><p>站在浪尖的那一批人早就开始思考<strong>让单机达到1000w并发</strong>，现在听起来感觉不可思议，但是要达到这个目标，除了硬件上的提升，更重要的是<strong>对系统软件和协议栈的改造</strong>。</p><p>Errata Security的CEO Robert Graham在Shmoocon 2013大会上的演讲，大佬重要的观点是：</p><blockquote><p><strong>不要让OS内核执行所有繁重的任务：将数据包处理、内存管理、处理器调度等任务从内核转移到应用程序高效地完成，让诸如Linux这样的OS只处理控制层，数据层完全交给应用程序来处理。</strong></p></blockquote><p>确实也是如此，<strong>难道你不觉得Linux内核做了太多不该自己做的事情了吗</strong>？</p><p>近几年出现的DPDK、PFRING、NETMAP等技术也是类似的思想，现在流行的协处理器+CPU的架构也是这样的：</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208281003486.png" alt="image-20220828100337409" style="zoom:67%;"><h2 id="_3-服务器最大并发数分析" tabindex="-1">3. 服务器最大并发数分析 <a class="header-anchor" href="#_3-服务器最大并发数分析" aria-label="Permalink to &quot;3. 服务器最大并发数分析&quot;">​</a></h2><p>前面提到的C10K和C10M问题都是围绕着提升服务器并发能力展开的，但是难免要问：<strong>服务器最大的并发上限是多少</strong>？</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208281003278.png" alt="image-20220828100350177" style="zoom:50%;"><h3 id="_3-1-五元组" tabindex="-1">3.1 五元组 <a class="header-anchor" href="#_3-1-五元组" aria-label="Permalink to &quot;3.1 五元组&quot;">​</a></h3><p>做过通信的盆友们一定听过<strong>五元组</strong>这个概念，一个五元组可以唯一标记一个网络连接，所以要理解和分析最大并发数，就必须理解五元组：</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208281004510.png" alt="image-20220828100408432" style="zoom:80%;"><p>这样的话，就可以基本认为：<strong>理论最大并发数 = 服务端唯一五元组数</strong>。</p><h3 id="_3-2-端口-ip组合数" tabindex="-1">3.2 端口&amp;IP组合数 <a class="header-anchor" href="#_3-2-端口-ip组合数" aria-label="Permalink to &quot;3.2 端口&amp;IP组合数&quot;">​</a></h3><p>那么对于服务器来说，服务端唯一五元组数最大是多少呢？</p><p><strong>有人说是65535</strong>，显然不是，但是之所以会有这类答案是因为当前Linux的端口号是2字节大小的short类型，总计2^16个端口，除去一些系统占用的端口，可用端口确实只剩下64000多了。</p><p>对于服务端本身来说，DestPort数量确实有限，假定有多张网卡，每个网卡绑定多个IP，<strong>服务端的Port端口数和IP数的组合类型也是有限的</strong>。</p><p>对于客户端来说，本身的端口和IP也是一样有限的，虽然这是个<strong>组合问题</strong>，但是数量还是有限的：</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208281005766.png" alt="image-20220828100556660" style="zoom:50%;"><h3 id="_3-3-并发数理论极限" tabindex="-1">3.3 并发数理论极限 <a class="header-anchor" href="#_3-3-并发数理论极限" aria-label="Permalink to &quot;3.3 并发数理论极限&quot;">​</a></h3><p>看了前面的端口&amp;IP的组合数计算，好像并发数并不会特别大。</p><p><strong>错了，是真的会很大。</strong></p><p>分析一下，前面的计算都是针对单个服务器或者客户端的，但是<strong>实际上每个服务器会应对全网的所有客户端</strong>，那么从服务端看，源IP和源Port的数量是非常大的。</p><p><strong>理论上服务端可以接受的客户端IP是2^32(按照IPv4计算）,端口数是2^16，目前端口号仍然是16bit的，所有这个理论最大值是2^48</strong>，果然很大！</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208281006836.png" alt="image-20220828100609745" style="zoom:67%;"><h3 id="_3-4-实际情况" tabindex="-1">3.4 实际情况 <a class="header-anchor" href="#_3-4-实际情况" aria-label="Permalink to &quot;3.4 实际情况&quot;">​</a></h3><p>天下没有免费的午餐。</p><p><strong>每一条连接都是要消耗系统资源的</strong>，所以实际中可能会设置最大并发数来保证服务器的安全和稳定，所以<strong>这个理论最大并发数是不可能达到的</strong>。</p><p><strong>实际中并发数和业务是直接相关的</strong>，像Redis这种内存型的服务端并发十几万都是没问题的，大部分来讲几十/几百/几千/几万等是存在的。</p><h2 id="_4-客户端最大连接数" tabindex="-1">4. 客户端最大连接数 <a class="header-anchor" href="#_4-客户端最大连接数" aria-label="Permalink to &quot;4. 客户端最大连接数&quot;">​</a></h2><p>理解了服务器的最大并发数是2^48，那么<strong>客户端最多可以连接多少服务器呢</strong>？</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208281006875.png" alt="image-20220828100622786" style="zoom:50%;"><p>对于客户端来说，当然可以借助于多网卡多IP来增加连接能力，我们仍然假定客户端只有1张网卡1个IP，由于端口数的限制到2^16，再去掉系统占用的端口，剩下可用的差不多64000。</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208281006316.png" alt="image-20220828100636233" style="zoom:67%;"><p>也就是说，客户端虽然可以连接任意的目的IP和目的端口，但是客户端自身端口是有限的，所以<strong>客户端的理论最大连接数是2^16</strong>，含系统占用端口。</p><h2 id="_5-nat环境下的客户端" tabindex="-1">5. NAT环境下的客户端 <a class="header-anchor" href="#_5-nat环境下的客户端" aria-label="Permalink to &quot;5. NAT环境下的客户端&quot;">​</a></h2><p>解决前面的两个问题之后，来看另外一个问题：</p><blockquote><p><strong>一个公网出口NAT服务设备最多可同时支持多少内网IP并发访问外网服务？</strong></p></blockquote><p>毕竟公网IP都是有限并且要花钱的，我们大部分机器都是在局域网中结合NAT来进行外网访问的，所以这个场景还是很熟悉的。</p><p>来看下<strong>内网机器访问外网时的IP&amp;端口替换和映射还原的过程</strong>，就明白了：</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.8.30/202208281006435.png" alt="image-20220828100655328" style="zoom:80%;"><p>因为这时的客户端是NAT设备，所以NAT环境下最多支持65535个并发访问外网。</p><h2 id="_6-小结" tabindex="-1">6.小结 <a class="header-anchor" href="#_6-小结" aria-label="Permalink to &quot;6.小结&quot;">​</a></h2><p>本文通过一道面试题切入，先描述了C10K和C10M问题，进而详细说明了客户端的最大访问数和服务端的最大并发数计算和原理，最后描述了NAT场景下的访问并发数。</p><p>虽然理论服务端并发数非常大，但是我们也没有必要觉得并发数高就厉害，服务复杂程度不一样，<strong>切忌唯并发数来判断业务和开发者水平</strong>。</p><p>试想echo服务和订单交易服务显然是不一样的，我们<strong>应该做的是在服务稳定和高可用的前提下去从缓存/网络/数据库等多个角度来优化提高性能</strong>。</p><h1 id="服务器被入侵怎么办" tabindex="-1">服务器被入侵怎么办 <a class="header-anchor" href="#服务器被入侵怎么办" aria-label="Permalink to &quot;服务器被入侵怎么办&quot;">​</a></h1><blockquote><p>下文中的，给文件和目录加锁，是指给文件和目录增加了一些属性，只读等</p></blockquote><h2 id="_1-服务器入侵现象" tabindex="-1">1 服务器入侵现象 <a class="header-anchor" href="#_1-服务器入侵现象" aria-label="Permalink to &quot;1 服务器入侵现象&quot;">​</a></h2><p>近期有一个朋友的服务器(自己做了网站)好像遭遇了入侵，具体现象是：服务器 CPU 资源长期 100%，负载较高。服务器上面的服务不能正常提供服务。</p><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.12.30/202211141220170.png" alt="image-20221114122027997" style="zoom:67%;"><p>朋友处理了一会没有解决，我开始想说我不是搞安全的，我怎么会，但朋友开出了天价，一顿海底捞，我在生活和现实面前低头了。开始上手看看了。</p><h2 id="_2-服务器排查和处理" tabindex="-1">2 服务器排查和处理 <a class="header-anchor" href="#_2-服务器排查和处理" aria-label="Permalink to &quot;2 服务器排查和处理&quot;">​</a></h2><h3 id="_1-服务器被入侵的可能原因" tabindex="-1">1 服务器被入侵的可能原因 <a class="header-anchor" href="#_1-服务器被入侵的可能原因" aria-label="Permalink to &quot;1 服务器被入侵的可能原因&quot;">​</a></h3><ol><li>服务器 ssh 密码 设置得很简单。</li><li>腾讯云安全组范围放得很大。</li><li>使用了宝塔，宝塔面板的密码也是很简单的密码(应该不是这个入侵入口)。</li></ol><h3 id="_2-排查和处理步骤" tabindex="-1">2 排查和处理步骤 <a class="header-anchor" href="#_2-排查和处理步骤" aria-label="Permalink to &quot;2 排查和处理步骤&quot;">​</a></h3><p>1、ps -ef / top 找出占用进程最大的服务</p><p>问题现象</p><p>ps/top 命令 已经被替换了。</p><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/knmrNHnmCLGlj7Vq66zrCVZ2YmniaFBZu6sUeIFZDORtmw6icdt8yvW6KKljib3tk7ibqwqZLdOdgrbcscX4rBxkNA/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>2、查找详细的入侵痕迹 last 或者 grep &#39;Accepted&#39; /var/log/secure。</p><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#FFCB6B;">grep</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">Accepted</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">  </span><span style="color:#C3E88D;">/var/log/secure</span></span></code></pre></div><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">root@VM-12-12-centos </span><span style="color:#89DDFF;">~]</span><span style="color:#A6ACCD;"># grep </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">Accepted</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">  /var/log/secure </span></span>
<span class="line"><span style="color:#FFCB6B;">Aug</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">26</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">21</span><span style="color:#C3E88D;">:51:37</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">VM-12-12-centos</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">sshd[</span><span style="color:#F78C6C;">19822</span><span style="color:#C3E88D;">]:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">Accepted</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">password</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">for</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">root</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">34.215</span><span style="color:#C3E88D;">.138.2</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">port</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">36720</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">ssh2</span></span>
<span class="line"><span style="color:#FFCB6B;">Aug</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">27</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">08</span><span style="color:#C3E88D;">:52:05</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">VM-12-12-centos</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">sshd[</span><span style="color:#F78C6C;">3053</span><span style="color:#C3E88D;">]:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">Accepted</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">password</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">for</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">root</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">127.0</span><span style="color:#C3E88D;">.0.1</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">port</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">57534</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">ssh2</span></span>
<span class="line"><span style="color:#FFCB6B;">Aug</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">27</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">08</span><span style="color:#C3E88D;">:58:50</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">VM-12-12-centos</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">sshd[</span><span style="color:#F78C6C;">7038</span><span style="color:#C3E88D;">]:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">Accepted</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">password</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">for</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">root</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">127.0</span><span style="color:#C3E88D;">.0.1</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">port</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">57548</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">ssh2</span></span>
<span class="line"><span style="color:#FFCB6B;">Aug</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">27</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">09</span><span style="color:#C3E88D;">:10:02</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">VM-12-12-centos</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">sshd[</span><span style="color:#F78C6C;">14830</span><span style="color:#C3E88D;">]:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">Accepted</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">publickey</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">for</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">lighthouse</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">106.55</span><span style="color:#C3E88D;">.203.49</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">port</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">44204</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">ssh2:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">RSA</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">SHA256:123456/UIbl8</span></span>
<span class="line"><span style="color:#FFCB6B;">Aug</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">27</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">09</span><span style="color:#C3E88D;">:10:03</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">VM-12-12-centos</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">sshd[</span><span style="color:#F78C6C;">14913</span><span style="color:#C3E88D;">]:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">Accepted</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">publickey</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">for</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">lighthouse</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">81.69</span><span style="color:#C3E88D;">.102.49</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">port</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">60820</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">ssh2:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">RSA</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">SHA256:123456/UIbl8</span></span>
<span class="line"><span style="color:#FFCB6B;">Aug</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">27</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">09</span><span style="color:#C3E88D;">:14:08</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">VM-12-12-centos</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">sshd[</span><span style="color:#F78C6C;">17307</span><span style="color:#C3E88D;">]:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">Accepted</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">password</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">for</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">root</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">127.0</span><span style="color:#C3E88D;">.0.1</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">port</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">57690</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">ssh2</span></span>
<span class="line"><span style="color:#FFCB6B;">Aug</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">27</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">09</span><span style="color:#C3E88D;">:34:22</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">VM-12-12-centos</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">sshd[</span><span style="color:#F78C6C;">29150</span><span style="color:#C3E88D;">]:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">Accepted</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">publickey</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">for</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">lighthouse</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">106.55</span><span style="color:#C3E88D;">.203.55</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">port</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">38044</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">ssh2:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">RSA</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">SHA256:123456/UIbl8</span></span>
<span class="line"><span style="color:#FFCB6B;">Aug</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">27</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">09</span><span style="color:#C3E88D;">:34:23</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">VM-12-12-centos</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">sshd[</span><span style="color:#F78C6C;">29233</span><span style="color:#C3E88D;">]:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">Accepted</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">publickey</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">for</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">lighthouse</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">from</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">81.69</span><span style="color:#C3E88D;">.102.60</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">port</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">51190</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">ssh2:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">RSA</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">SHA256:123456/UIbl8</span></span></code></pre></div><blockquote><p>lighthouse 腾讯云轻量服务器</p></blockquote><p>我们在这里就可以看到，有一些境外IP 34.215.138.2 成功登录了，这些 IP不是我们的正常登录。在 /var/log/secure 日志里，我看到了 IP 34.215.138.2 尝试登录不到500次 就已经破解成功了。</p><h3 id="_3-处理措施" tabindex="-1">3 处理措施 <a class="header-anchor" href="#_3-处理措施" aria-label="Permalink to &quot;3 处理措施&quot;">​</a></h3><p>这里我们立马采取了第一个措施，</p><ol><li>在腾讯云安全组限制了 SSH 的登录IP， 之前的安全组 SSH 是放行所有IP。</li><li>将 SSH ROOT 密码修改。</li><li>/root/.ssh/authorized_keys 备份，并清空。</li></ol><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">root@VM-12-12-centos </span><span style="color:#89DDFF;">~]</span><span style="color:#A6ACCD;"># cp -rp /root/.ssh/authorized_keys  /root/.ssh/authorized_keys.bak</span></span>
<span class="line"><span style="color:#FFCB6B;">cp:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">cannot</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">create</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">regular</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">file</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">‘/root/.ssh/authorized_keys.bak’:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">Permission</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">denied</span></span></code></pre></div><p>这时我们就遇到了权限的问题，这个晚点展开讲，因为我们已经限制了源IP， 所以这个我们可以晚点来处理。</p><p>3、查看最近新增的一些用户</p><p>问题现象</p><div class="language-s"><button title="Copy Code" class="copy"></button><span class="lang">s</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">cat /etc/passwd</span></span></code></pre></div><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.12.30/202211141223034.png" alt="image-20221114122321891" style="zoom:80%;"><p><strong>处理措施</strong></p><p>锁定用户</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">[root@VM-12-12-centos ~]# usermod  -L  sys1</span></span></code></pre></div><p>4、我这里不计划去找进程（已经在新建一台版本一致的系统， 来拷贝 top 和 ps 命令，需要一小会，我们趁这个时间，先看看其他），因为之前朋友重启过服务器，发现服务器启动过一会才会负载较高。我认为入侵者应该放了一些定时任务和启动脚本里面。</p><p><strong>问题现象</strong></p><p>定时任务</p><p>crond 读取配置文件会从以下几个路径读取：</p><ul><li>/var/spool/cron/ , 由crontab -e 进行写入，配置文件无需指定用户</li><li>/etc/crontab ，只能root 进行编辑，配置文件需指定用户</li><li>/etc/cron.d/ ,在此文件夹下创建定时任务文件，配置文件需指定用户</li><li>/etc/cron.*</li></ul><p>/var/spool/cron/ 未找到(后面会说到这里有障眼法)</p><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/knmrNHnmCLGlj7Vq66zrCVZ2YmniaFBZu1m44NHdgrcLsr3YSYQEx1MKjibzc1HFMIDqch7ydCdguibSUmXQJHE5g/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>图片</p><p>/etc/crontab 未找到(后面会说到这里有障眼法)</p><p>但是我在 /var/log/cron 一直看到有任务执行。每间隔5分钟。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">Aug 27 22:00:01 VM-12-12-centos CROND[16839]: (root) CMD (/sbin/httpss &gt;/dev/null 2&gt;&amp;1;^M                                                                                                    )</span></span>
<span class="line"><span style="color:#A6ACCD;">Aug 27 22:00:01 VM-12-12-centos CROND[16840]: (root) CMD (/usr/local/qcloud/YunJing/YDCrontab.sh &gt; /dev/null 2&gt;&amp;1)</span></span>
<span class="line"><span style="color:#A6ACCD;">Aug 27 22:00:01 VM-12-12-centos CROND[16842]: (root) CMD (/usr/lib/mysql/mysql;^Mno crontab for root                                                                                                   )</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">Aug 27 22:05:01 VM-12-12-centos CROND[17486]: (root) CMD (/usr/lib/mysql/mysql;^Mno crontab for root                                                                                                   )</span></span>
<span class="line"><span style="color:#A6ACCD;">Aug 27 22:05:01 VM-12-12-centos CROND[17487]: (root) CMD (/sbin/httpss &gt;/dev/null 2&gt;&amp;1;^M                                                                                                    )</span></span></code></pre></div><p><strong>处理措施</strong></p><p>这里我们先做的操作就是，先把 /usr/lib/mysql/mysql 和 /sbin/httpss 给删除。删除的时候还是提示没有权限。我们知道这些文件应该是加琐了，所以我开始解锁，我们发现 chattr 也被替换和锁住了。所以不能操作下去了。</p><p>开机启动脚本</p><p>/etc/rc.local ， 我们也发现了一个脚本。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">[root@VM-12-12-centos ~]# cat /etc/rc.local </span></span>
<span class="line"><span style="color:#A6ACCD;">#!/bin/bash</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;"># THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES</span></span>
<span class="line"><span style="color:#A6ACCD;">#</span></span>
<span class="line"><span style="color:#A6ACCD;"># It is highly advisable to create own systemd services or udev rules</span></span>
<span class="line"><span style="color:#A6ACCD;"># to run scripts during boot instead of using this file.</span></span>
<span class="line"><span style="color:#A6ACCD;">#</span></span>
<span class="line"><span style="color:#A6ACCD;"># In contrast to previous versions due to parallel execution during boot</span></span>
<span class="line"><span style="color:#A6ACCD;"># this script will NOT be run after all other services.</span></span>
<span class="line"><span style="color:#A6ACCD;">#</span></span>
<span class="line"><span style="color:#A6ACCD;"># Please note that you must run &#39;chmod +x /etc/rc.d/rc.local&#39; to ensure</span></span>
<span class="line"><span style="color:#A6ACCD;"># that this script will be executed during boot.</span></span>
<span class="line"><span style="color:#A6ACCD;"></span></span>
<span class="line"><span style="color:#A6ACCD;">/usr/bin/0f4f80f9ab start</span></span></code></pre></div><p>但是这个文件好像不存在的，我们就把这个给注释了。</p><p>5、还原更改了 top、ps、chattr、lsattr.</p><ul><li>首先我们从相同版本的机器拷贝了 chattr、lsattr， 我们得先操作这个， 因为我们的 top 和 ps 都被锁住了。</li><li>我将文件上传至 /tmp 目录，然后增加可执行权限，然后先给 /usr/bin/chattr 解除锁定。</li></ul><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">/tmp/chattr -ai /usr/bin/chattr</span></span></code></pre></div><ul><li>执行完之后，发现还是不能替换 /usr/bin/chattr。最后耗费了一段时间才反应到，入侵者可能不仅仅加锁了文件还加锁了 /usr/bin/。</li><li>解锁目录</li></ul><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;">/tmp/chattr -ai /usr/bin/</span></span></code></pre></div><ul><li>这下才能把 /usr/bin/chattr 给替换掉。</li><li>接下来参考这些，我们把 top 和 ps 、lsattr 给还原了。</li></ul><p>部分截图</p><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/knmrNHnmCLGlj7Vq66zrCVZ2YmniaFBZuwJibY3Dibaat6ZWm4k7N7Ol7KibD3TE1UJn54kJWgSxm1rWVIgHJibACTw/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><h2 id="_3-本次入侵需要带来启示的点" tabindex="-1">3 本次入侵需要带来启示的点 <a class="header-anchor" href="#_3-本次入侵需要带来启示的点" aria-label="Permalink to &quot;3 本次入侵需要带来启示的点&quot;">​</a></h2><h3 id="_1-ps-、top-、chattr-、lsattr" tabindex="-1">1 ps 、top 、chattr 、lsattr <a class="header-anchor" href="#_1-ps-、top-、chattr-、lsattr" aria-label="Permalink to &quot;1 ps 、top 、chattr 、lsattr&quot;">​</a></h3><p>在这些命令被替换了，并且我们想还原又还原不了的场景，我们可以拷贝同版本的机器相同的命令放在其它目录，用这些命令来解除入侵者将它已经替换并锁定了文件。注意有些入侵者不仅会在文件层面加锁，还会在当前的文件的目录这一层加锁。我之前在这个上面困惑了一段时间。</p><h3 id="_2-文件内容隐藏" tabindex="-1">2 文件内容隐藏 <a class="header-anchor" href="#_2-文件内容隐藏" aria-label="Permalink to &quot;2 文件内容隐藏&quot;">​</a></h3><p>上文中，我执行 crontab -l 和 cat 查看 /etc/cron.d/ 下面的文件。发现文件没有内容。</p><p>其实不知道使用了什么特殊字符还是什么隐藏了， 其实是存在定时任务的。</p><p>示例：</p><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/knmrNHnmCLGlj7Vq66zrCVZ2YmniaFBZu3xazn1HZLEbEjJLKPaRYoXibGf0uknlk3FAW3vJdXk29p0PprzPrRdw/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/knmrNHnmCLGlj7Vq66zrCVZ2YmniaFBZuvXS7s8E7ZPZWXRic8I1Njl15HOxEBoARs3yZWqG3Nm8kICOkwDtStEQ/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/knmrNHnmCLGlj7Vq66zrCVZ2YmniaFBZuMPxibepT7CP8ll68GTVaOlGQJ5BDnTugnHCwvMEvWibG2vK1yynLxPsg/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>这个配置是如何导致 cat/more 看不了的, 今天再次看了下，这个文件可能是被当成了数据文件，因为我把这个文件 file 查看了之后，文件属性是data. 然后文件包含的特殊字符，导致隐藏了。</p><h3 id="_3-其中一个脚本" tabindex="-1">3 其中一个脚本 <a class="header-anchor" href="#_3-其中一个脚本" aria-label="Permalink to &quot;3 其中一个脚本&quot;">​</a></h3><p>我们可以看到这个脚本其实一直在 更改 /etc/ld.so.preload 的内容。并且在关闭一些扫描软件和系统的服务。</p><blockquote><p>在 Linux 操作系统的动态链接库加载过程中，动态链接器会读取 LD_PRELOAD 环境变量的值和默认配置文件 /etc/ld.so.preload 的文件内容，并将读取到的动态链接库进行预加载，即使程序不依赖这些动态链接库，LD_PRELOAD 环境变量和 /etc/ld.so.preload 配置文件中指定的动态链接库依然会被装载，它们的优先级比 LD_LIBRARY_PATH 环境变量所定义的链接库查找路径的文件优先级要高，所以能够提前于用户调用的动态库载入。——段落引自《警惕利用 Linux 预加载型恶意动态链接库的后门》</p></blockquote><p>我已经删除了 /usr/local/lib/libprocesshider.so 文件，之后每次执行命令会有这个报错。</p><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/knmrNHnmCLGlj7Vq66zrCVZ2YmniaFBZuQgBSXhn0b2lSxpH3R170RTFX8oqrSjaSltHmhy7qkHXtxMINXCUQnQ/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>我在清空文件 /etc/ld.so.preload 之后，我发现好了一会后，还是出现这个，我再看 /etc/ld.so.preload 文件，里面又写了 /usr/local/lib/libprocesshider.so ，我怀疑还有定时任务，但是我找了一会定时任务，还是没有找到。后面在查看异常进程的时候，我看到了这个进程</p><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/knmrNHnmCLGlj7Vq66zrCVZ2YmniaFBZu2n59rzVib78Oj26saUJO7bIDTA4x5l4Aic3k8iaWx9Jj394v3K1cm9ghA/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/knmrNHnmCLGlj7Vq66zrCVZ2YmniaFBZu3zeS9pVT5ibMwoicBoKkpKT030O8e2DmNTZpDkSJwh4Be6BibuE5V2Zaw/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>发现这个脚本的就是一直在循环执行上面内容。将这个进程 kill 后，然后删除脚本。</p><h2 id="_4-本次服务器被入侵的一些启示" tabindex="-1">4 本次服务器被入侵的一些启示 <a class="header-anchor" href="#_4-本次服务器被入侵的一些启示" aria-label="Permalink to &quot;4 本次服务器被入侵的一些启示&quot;">​</a></h2><p>1、用好云厂家的安全组。对一些关键端口，放行规则尽量最小/</p><p>2、服务器相关的一些密码尽量增加复杂性。</p><p>3、增加对一些关键文件的监控. (通过监控软件监控 md5值)</p><ul><li>/etc/passwd</li><li>/etc/shadow</li><li>/etc/group</li><li>/root/.bash_history</li><li>/root/.ssh/authorized_keys</li><li>/etc/ssh/sshd_config</li><li>/etc/profile</li><li>/var/spool/cron/root</li><li>/etc/crontab</li><li>/etc/ld.so.preload</li><li>/etc/rc.local</li><li>lsof</li><li>ps</li><li>netstat</li><li>top</li><li>ls</li><li>pstree</li><li>last</li><li>history</li><li>sudo</li><li>password</li><li>chattr</li><li>lsattr</li></ul><p>4、服务器入侵之后，我们需要怎么处理才是最好的。</p><blockquote><p><a href="https://cloud.tencent.com/document/product/296/9604" target="_blank" rel="noreferrer">https://cloud.tencent.com/document/product/296/9604</a> <a href="https://help.aliyun.com/document_detail/40994.htm?spm=a2c4g.11186623.0.0.75c56956NVPBST" target="_blank" rel="noreferrer">https://help.aliyun.com/document_detail/40994.htm?spm=a2c4g.11186623.0.0.75c56956NVPBST</a></p></blockquote><ol><li>服务器如果有开放SSH 远程登录，可以设置限制登录(安全组、或者服务)，只放行自己的IP. 查找详细的入侵痕迹 last 或者 grep &#39;Accepted&#39; /var/log/secure</li></ol><blockquote><p>/root/.ssh/authorized_keys /etc/passwd 这些文件也可以看下。将一些新建的用户锁定。</p></blockquote><ol><li>服务器如果可以关闭外网，就关闭外网。在安全组层面设置下，或者路由或者NAT。</li><li>首先看下 ps/top 命令有没有被篡改， 如果有的话， 从其他正常的机器上拷贝至服务器上。然后执行查看异常进程。也要查询下 /etc/ld.so.preload 是否有被篡改。如果有的的话，记得清空里面的内容，然后将对应的文件删除或者重命名。</li></ol><blockquote><p>如果使用过程中遇到了文件不可删，不可改的问题，需要使用 chattr -ia 文件名 如果 chattr 也被串改，那就需要从别的机器拷贝。然后复原。</p></blockquote><ol><li>如果上述没有找到，可以通过 netstat 间接查看异常的连接从而查询异常进程。</li><li>检查开机启动 和 crontab 相关的内容 。</li><li>检查异常进程。</li></ol><p>以上就是这次入侵的处理过程和得到的一些小启示，后续有了解新的会继续补充。</p><h1 id="linux-网络性能的-15-个优化建议" tabindex="-1">Linux 网络性能的 15 个优化建议 <a class="header-anchor" href="#linux-网络性能的-15-个优化建议" aria-label="Permalink to &quot;Linux 网络性能的 15 个优化建议&quot;">​</a></h1><p>Linux 网络在性能方面有哪些优化手段可用呢？本文将给出一些开发或者运维中的 Linux 网络性能优化建议。</p><p>要注意的是，每一种性能优化方法都有它适用或者不适用的应用场景，根据当前的项目现状灵活来选择用或者不用。</p><h2 id="尽量减少不必要的网络-io" tabindex="-1">尽量减少不必要的网络 IO <a class="header-anchor" href="#尽量减少不必要的网络-io" aria-label="Permalink to &quot;尽量减少不必要的网络 IO&quot;">​</a></h2><p>第一个建议就是不必要用网络 IO 的尽量不用。</p><p>是的，网络在现代的互联网世界里承载了很重要的角色。用户通过网络请求线上服务、服务器通过网络读取数据库中数据，通过网络构建能力无比强大分布式系统。网络很好，能降低模块的开发难度，也能用它搭建出更强大的系统。但是这不是你滥用它的理由！</p><p>原因是即使是本机网络 IO 开销仍然是很大的。先说发送一个网络包，首先得从用户态切换到内核态，花费一次系统调用的开销。进入到内核以后，又得经过冗长的协议栈，这会花费不少的 CPU 周期，最后进入环回设备的“驱动程序”。接收端呢，软中断花费不少的 CPU 周期又得经过接收协议栈的处理，最后唤醒或者通知用户进程来处理。当服务端处理完以后，还得把结果再发过来。又得来这么一遍，最后你的进程才能收到结果。你说麻烦不麻烦。另外还有个问题就是多个进程协作来完成一项工作就必然会引入更多的进程上下文切换开销，这些开销从开发视角来看，做的其实都是无用功。</p><p>上面分析的还只是本机网络 IO，如果是跨机器的还得会有双方网卡的 DMA 拷贝过程，以及两端之间的网络 RTT 耗时延迟。所以，网络虽好，但也不能随意滥用！</p><h2 id="尽量合并网络请求" tabindex="-1">尽量合并网络请求 <a class="header-anchor" href="#尽量合并网络请求" aria-label="Permalink to &quot;尽量合并网络请求&quot;">​</a></h2><p>在可能的情况下，尽可能地把多次的网络请求合并到一次，这样既节约了双端的 CPU 开销，也能降低多次 RTT 导致的耗时。我们举个实践中的例子可能更好理解。假如有一个 redis，里面存了每一个 App 的信息（应用名、包名、版本、截图等等）。你现在需要根据用户安装应用列表来查询数据库中有哪些应用比用户的版本更新，如果有则提醒用户更新。</p><p>那么最好不要写出如下的代码：</p><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">&lt;?</span><span style="color:#A6ACCD;">php </span></span>
<span class="line"><span style="color:#A6ACCD;">for</span><span style="color:#89DDFF;">(</span><span style="color:#FFCB6B;">安装列表</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">as</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">包名</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">redis-&gt;get(包名</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">...</span></span>
<span class="line"><span style="color:#A6ACCD;">}</span></span></code></pre></div><blockquote><p>上面这段代码功能实现上没问题，问题在于性能。据我们统计现代用户平均安装 App 的数量在 60 个左右。那这段代码在运行的时候，每当用户来请求一次，你的服务器就需要和 redis 进行 60 次网络请求。总耗时最少是 60 个 RTT 起。更好的方法是应该使用 redis 中提供的批量获取命令，如 hmget、pipeline 等，经过一次网络 IO 就获取到所有想要的数据，如图。</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.1.30/202212291551884.png" alt="image-20221229155156753" style="zoom:67%;"><h2 id="调用者与被调用机器尽可能部署得近" tabindex="-1">调用者与被调用机器尽可能部署得近 <a class="header-anchor" href="#调用者与被调用机器尽可能部署得近" aria-label="Permalink to &quot;调用者与被调用机器尽可能部署得近&quot;">​</a></h2><blockquote><p>我们知道，在握手一切正常的情况下，TCP 握手的时间基本取决于两台机器之间的 RTT 耗时。虽然我们没办法彻底去掉这个耗时，但是我们却有办法把 RTT 降低，那就是把客户端和服务器放得足够的近一些。尽量把每个机房内部的数据请求都在本地机房解决，减少跨地网络传输。</p></blockquote><blockquote><p>举例，假如你的服务是部署在北京机房的，你调用的 mysql、redis 最好都位于北京机房内部。尽量不要跨过千里万里跑到广东机房去请求数据，即使你有专线，耗时也会大大增加！在机房内部的服务器之间的 RTT 延迟大概只有零点几毫秒，同地区的不同机房之间大约是 1 ms 多一些。但如果从北京跨到广东的话，延迟将是 30 - 40 ms 左右，几十倍的上涨！</p></blockquote><h2 id="内网调用不要用外网域名" tabindex="-1">内网调用不要用外网域名 <a class="header-anchor" href="#内网调用不要用外网域名" aria-label="Permalink to &quot;内网调用不要用外网域名&quot;">​</a></h2><p>假如说你所负责的服务需要调用兄弟部门的一个搜索接口，假设接口是：&quot;<a href="http://www.sogou.com/wq?key=%E5%BC%80%E5%8F%91" target="_blank" rel="noreferrer">http://www.sogou.com/wq?key=开发</a>&quot;。</p><p>既然是兄弟部门，那很可能这个接口和你的服务是部署在一个机房的。即使没有部署在一个机房，一般也是有专线可达的。<strong>所以不要直接请求 www.sogou.com，而是应该使用该服务在公司对应的内网域名</strong>。在我们公司内部，每一个外网服务都会配置一个对应的内网域名，我相信你们公司也有。</p><p>为什么要这么做，原因有以下几点：</p><p>1）<strong>外网接口慢</strong>。本来内网可能过个交换机就能达到兄弟部门的机器，非得上外网兜一圈再回来，时间上肯定会慢。</p><p>2）<strong>带宽成本高</strong>。在互联网服务里，除了机器以外，另外一块很大的成本就是 IDC 机房的出入口带宽成本。两台机器在内网不管如何通信都不涉及到带宽的计算。但是一旦你去外网兜了一圈回来，行了，一进一出全部要缴带宽费，你说亏不亏！！</p><p>3）<strong>NAT 单点瓶颈</strong>。一般的服务器都没有外网 IP，所以要想请求外网的资源，必须要经过 NAT 服务器。但是一个公司的机房里几千台服务器中，承担 NAT 角色的可能就那么几台。它很容易成为瓶颈。我们的业务就遇到过好几次 NAT 故障导致外网请求失败的情形。NAT 机器挂了，你的服务可能也就挂了，故障率大大增加。</p><h2 id="调整网卡-ringbuffer-大小" tabindex="-1">调整网卡 RingBuffer 大小 <a class="header-anchor" href="#调整网卡-ringbuffer-大小" aria-label="Permalink to &quot;调整网卡 RingBuffer 大小&quot;">​</a></h2><p>在 Linux 的整个网络栈中，RingBuffer 充当了一个任务的收发中转站的角色。对于接收过程来讲，网卡负责往 RingBuffer 中写入收到的数据帧，ksoftirqd 内核线程负责从中取走处理。只要 ksoftirqd 线程工作得足够快，RingBuffer 这个中转站就不会出现问题。</p><p>但是我们设想一下，假如某一时刻，瞬间来了特别多的包，而 ksoftirqd 处理不过来了，会发生什么？这时 RingBuffer 可能瞬间就被填满了，后面再来的包，网卡直接就会丢弃，不做任何处理！</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwrXUoWVbHSG80ibNxjChtjUkfqTshFY2YR7LZQDKC8608oNowSLbNG6qa8dK9Ee81LWQc9zeTib1t7A/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>通过 ethtool 就可以加大 RingBuffer 这个“中转仓库”的大小。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;"># ethtool -G eth1 rx 4096 tx 4096</span></span></code></pre></div><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwrXUoWVbHSG80ibNxjChtjUkicDXQPeysibT7yWt3iadJU9A5pdorMQFLoyV2H1QBolTNE8J2xNDVIa1A/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>这样网卡会被分配更大一点的“中转站”，可以解决偶发的瞬时的丢包。不过这种方法有个小副作用，那就是排队的包过多会增加处理网络包的延时。所以应该让内核处理网络包的速度更快一些更好，而不是让网络包傻傻地在 RingBuffer 中排队。</p><h2 id="减少内存拷贝" tabindex="-1">减少内存拷贝 <a class="header-anchor" href="#减少内存拷贝" aria-label="Permalink to &quot;减少内存拷贝&quot;">​</a></h2><p>假如你要发送一个文件给另外一台机器，那么比较基础的做法是先调用 read 把文件读出来，再调用 send 把数据把数据发出去。这样数据需要频繁地在内核态内存和用户态内存之间拷贝，如图所示。</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwrXUoWVbHSG80ibNxjChtjUkHHhNfovoBqB8yic9k3icGBb3MDUoNzciaSGjNlT1j0vXVOF6HlAp3esGw/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>目前减少内存拷贝主要有两种方法，分别是使用 mmap 和 sendfile 两个系统调用。使用 mmap 系统调用的话，映射进来的这段地址空间的内存在用户态和内核态都是可以使用的。如果你发送的数据是 mmap 映射进来的数据，则内核直接就可以从地址空间中读取，这样就节约了一次从内核态到用户态的拷贝过程。</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwrXUoWVbHSG80ibNxjChtjUkp74cONt3RZZZAAAWgaOTQhicDgyKXBTh76sjtsMXUcmynGiaMeaiadQBQ/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><p>不过在 mmap 发送文件的方式里，系统调用的开销并没有减少，还是发生两次内核态和用户态的上下文切换。如果你只是想把一个文件发送出去，而不关心它的内容，则可以调用另外一个做得更极致的系统调用 - sendfile。在这个系统调用里，彻底把读文件和发送文件给合并起来了，系统调用的开销又省了一次。再配合绝大多数网卡都支持的&quot;分散-收集&quot;（Scatter-gather）DMA 功能。可以直接从 PageCache 缓存区中 DMA 拷贝到网卡中。这样绝大部分的 CPU 拷贝操作就都省去了。</p><p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwrXUoWVbHSG80ibNxjChtjUktOOkKcm4TSDvxOcPJVJL85t62vyOLGbNL0N0mRsz35QR62D90icW5Jw/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片"></p><h2 id="使用-ebpf-绕开协议栈的本机-io" tabindex="-1">使用 eBPF 绕开协议栈的本机 IO <a class="header-anchor" href="#使用-ebpf-绕开协议栈的本机-io" aria-label="Permalink to &quot;使用 eBPF 绕开协议栈的本机 IO&quot;">​</a></h2><p>如果你的业务中涉及到大量的本机网络 IO，可以考虑这个优化方案。本机网络 IO 和跨机 IO 比较起来，确实是节约了驱动上的一些开销。发送数据不需要进 RingBuffer 的驱动队列，直接把 skb 传给接收协议栈（经过软中断）。但是在内核其它组件上，可是一点都没少，系统调用、协议栈（传输层、网络层等）、设备子系统整个走了一个遍。连“驱动”程序都走了（虽然对于回环设备来说这个驱动只是一个纯软件的虚拟出来的东东）。</p><p>如果想用本机网络 IO，但是又不想频繁地在协议栈中绕来绕去。那么你可以试试 eBPF。使用 eBPF 的 sockmap 和 sk redirect 可以绕过 TCP/IP 协议栈，而被直接发送给接收端的 socket，业界已经有公司在这么做了。</p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwrXUoWVbHSG80ibNxjChtjUkyT4yaoiaZJJlujhQVf6VD4komc8gZiaMK49icnrp1f912AT19u45S4wrA/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片" style="zoom:67%;"><h2 id="尽量少用-recvfrom-等进程阻塞方式" tabindex="-1">尽量少用 recvfrom 等进程阻塞方式 <a class="header-anchor" href="#尽量少用-recvfrom-等进程阻塞方式" aria-label="Permalink to &quot;尽量少用 recvfrom 等进程阻塞方式&quot;">​</a></h2><p>在使用了 recvfrom 阻塞方式来接收 socket 上数据的时候，每次一个进程专⻔为了等一个 socket 上的数据就得被从 CPU 上拿下来，然后再换上另一个 进程。等到数据 ready 了，睡眠的进程又会被唤醒。总共两次进程上下文切换开销。如果我们服务器上有大量的用户请求需要处理，那就需要有很多的进程存在，而且不停地切换来切换去。这样的缺点有如下几个：</p><ul><li>因为每个进程只能同时等待一条连接，所以需要大量的进程。</li><li>进程之间互相切换的时候需要消耗很多 CPU 周期，一次切换大约是 3 - 5 us 左右。</li><li>频繁的切换导致 L1、L2、L3 等高速缓存的效果大打折扣。</li></ul><p>大家可能以为这种网络 IO 模型很少见了。但其实在很多传统的客户端 SDK 中，比如 mysql、redis 和 kafka 仍然是沿用了这种方式。</p><h2 id="使用成熟的网络库" tabindex="-1">使用成熟的网络库 <a class="header-anchor" href="#使用成熟的网络库" aria-label="Permalink to &quot;使用成熟的网络库&quot;">​</a></h2><p>使用 epoll 可以高效地管理海量的 socket。在服务器端，我们有各种成熟的网络库进行使用。这些网络库都对 epoll 使用了不同程度的封装。</p><blockquote><p>首先第一个要给大家参考的是 Redis。老版本的 Redis 里单进程高效地使用 epoll 就能支持每秒数万 QPS 的高性能。如果你的服务是单进程的，可以参考 Redis 在网络 IO 这块的源码。</p></blockquote><blockquote><p>如果是多线程的，线程之间的分工有很多种模式。那么哪个线程负责等待读 IO 事件，哪个线程负责处理用户请求，哪个线程又负责给用户写返回。根据分工的不同，又衍生出单 Reactor、多 Reactor、以及 Proactor 等多种模式。大家也不必头疼，只要理解了这些原理之后，选择一个性能不错的网络库就可以了。比如 PHP 中的 Swoole、Golang 的 net 包、Java 中的 netty、C++ 中的 Sogou Workflow 都封装得非常的不错。</p></blockquote><h2 id="使用-kernel-bypass-新技术" tabindex="-1">使用 Kernel-ByPass 新技术 <a class="header-anchor" href="#使用-kernel-bypass-新技术" aria-label="Permalink to &quot;使用 Kernel-ByPass 新技术&quot;">​</a></h2><p>如果你的服务对网络要求确实特别特别的高，而且各种优化措施也都用过了，那么现在还有终极优化大招 -- Kernel-ByPass 技术。</p><p>内核在接收网络包的时候，要经过很⻓的收发路径。在这期间牵涉到很多内核组件之间的协同、协议栈的处理、以及内核态和用户态的拷贝和切换。Kernel-ByPass 这类的技术方案就是绕开内核协议栈，自己在用户态来实现网络包的收发。这样不但避开了繁杂的内核协议栈处理，也减少了频繁的内核态用户态之间的拷贝和切换，性能将发挥到极致！</p><p>目前我所知道的方案有 SOLARFLARE 的软硬件方案、DPDK 等等。如果大家感兴趣，可以多去了解一下！</p><img src="https://mmbiz.qpic.cn/mmbiz_png/BBjAFF4hcwrXUoWVbHSG80ibNxjChtjUkGibp3vHPPoUfTmiarzCIgFL3AvobdIRu53uvLupAsSZREEEJXatoLHhg/640?wx_fmt=png&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="图片" style="zoom:50%;"><h2 id="配置充足的端口范围" tabindex="-1">配置充足的端口范围 <a class="header-anchor" href="#配置充足的端口范围" aria-label="Permalink to &quot;配置充足的端口范围&quot;">​</a></h2><p>客户端在调用 connect 系统调用发起连接的时候，需要先选择一个可用的端口。内核在选用端口的时候，是采用从可用端口范围中某一个随机位置开始遍历的方式。如果端口不充足的话，内核可能需要循环撞很多次才能选上一个可用的。这也会导致花费更多的 CPU 周期在内部的哈希表查找以及可能的自旋锁等待上。因此不要等到端口用尽报错了才开始加大端口范围，而是应该一开始的时候就保持一个比较充足的值。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;"># vi /etc/sysctl.conf</span></span>
<span class="line"><span style="color:#A6ACCD;">net.ipv4.ip_local_port_range = 5000 65000</span></span>
<span class="line"><span style="color:#A6ACCD;"># sysctl -p  //使配置生效</span></span></code></pre></div><p>如果端口加大了仍然不够用，那么可以考虑开启端口 reuse 和 recycle。这样端口在连接断开的时候就不需要等待 2MSL 的时间了，可以快速回收。开启这个参数之前需要保证 tcp_timestamps 是开启的。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;"># vi /etc/sysctl.conf</span></span>
<span class="line"><span style="color:#A6ACCD;">net.ipv4.tcp_timestamps = 1</span></span>
<span class="line"><span style="color:#A6ACCD;">net.ipv4.tcp_tw_reuse = 1</span></span>
<span class="line"><span style="color:#A6ACCD;">net.ipv4.tw_recycle = 1</span></span>
<span class="line"><span style="color:#A6ACCD;"># sysctl -p</span></span></code></pre></div><h2 id="小心连接队列溢出" tabindex="-1">小心连接队列溢出 <a class="header-anchor" href="#小心连接队列溢出" aria-label="Permalink to &quot;小心连接队列溢出&quot;">​</a></h2><p>服务器端使用了两个连接队列来响应来自客户端的握手请求。这两个队列的长度是在服务器 listen 的时候就确定好了的。如果发生溢出，很可能会丢包。所以如果你的业务使用的是短连接且流量比较大，那么一定得学会观察这两个队列是否存在溢出的情况。因为一旦出现因为连接队列导致的握手问题，那么 TCP 连接耗时都是秒级以上了。</p><p>对于半连接队列， 有个简单的办法。那就是只要保证 tcp_syncookies 这个内核参数是 1，就能保证不会有因为半连接队列满而发生的丢包。</p><p>对于全连接队列来说，可以通过 netstat -s 来观察。netstat -s 可查看到当前系统全连接队列满导致的丢包统计。但该数字记录的是总丢包数，所以你需要再借助 watch 命令动态监控。</p><div class="language-"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#A6ACCD;"># watch &#39;netstat -s | grep overflowed&#39; </span></span>
<span class="line"><span style="color:#A6ACCD;">160 times the listen queue of a socket overflowed //全连接队列满导致的丢包</span></span></code></pre></div><p>如果输出的数字在你监控的过程中变了，那说明当前服务器有因为全连接队列满而产生的丢包。你就需要加大你的全连接队列的⻓度了。全连接队列是应用程序调用 listen 时传入的 backlog 以及内核参数 net.core.somaxconn 二者之中较小的那个。如果需要加大，可能两个参数都需要改。</p><p>如果你手头并没有服务器的权限，只是发现自己的客户端机连接某个 server 出现耗时长，想定位一下是否是因为握手队列的问题。那也有间接的办法，可以 tcpdump 抓包查看是否有 SYN 的 TCP Retransmission。如果有偶发的 TCP Retransmission， 那就说明对应的服务端连接队列可能有问题了。</p><h2 id="减少握手重试" tabindex="-1">减少握手重试 <a class="header-anchor" href="#减少握手重试" aria-label="Permalink to &quot;减少握手重试&quot;">​</a></h2><p>我们知道，如果握手发生异常，客户端或者服务端就会启动超时重传机制。这个超时重试的时间间隔是翻倍地增长的，1 秒、3 秒、7 秒、15 秒、31 秒、63 秒 ......。对于我们提供给用户直接访问的接口来说，重试第一次耗时 1 秒多已经是严重影响用户体验了。如果重试到第三次以后，很有可能某一个环节已经报错返回 504 了。所以在这种应用场景下，维护这么多的超时次数其实没有任何意义。倒不如把他们设置得小一些，尽早放弃。其中客户端的 syn 重传次数由 tcp_syn_retries 控制，服务器半连接队列中的超时次数是由 tcp_synack_retries 来控制。把它们两个调成你想要的值。</p><h2 id="如果请求频繁-请弃用短连接改用长连接" tabindex="-1">如果请求频繁，请弃用短连接改用长连接 <a class="header-anchor" href="#如果请求频繁-请弃用短连接改用长连接" aria-label="Permalink to &quot;如果请求频繁，请弃用短连接改用长连接&quot;">​</a></h2><p>如果你的服务器频繁请求某个 server，比如 redis 缓存。和建议 1 比起来，一个更好一点的方法是使用长连接。这样的好处有：</p><p>1）<strong>节约了握手开销</strong>。短连接中每次请求都需要服务和缓存之间进行握手，每次都得让用户多等一个握手的时间开销</p><p>2）<strong>规避了队列满的问题</strong>。我们知道，当全连接或者半连接队列溢出的时候，服务器直接丢包。而客户端呢并不知情，所以傻傻地等 3 秒才会重试。要知道 tcp 本身并不是专门为互联网服务设计的，这个 3 秒的超时对于互联网用户的体验影响是致命的。</p><p>3）<strong>端口数不容易出问题</strong>。端连接中，在释放连接的时候，客户端使用的端口需要进入 TIME_WAIT 状态，等待 2 MSL 的时间才能释放。所以如果连接频繁，端口数量很容易不够用。而长连接就固定使用那么几十上百个端口就够用了。</p><h2 id="time-wait-的优化" tabindex="-1">TIME_WAIT 的优化 <a class="header-anchor" href="#time-wait-的优化" aria-label="Permalink to &quot;TIME_WAIT 的优化&quot;">​</a></h2><p>很多线上服务如果使用了短连接的情况下，就会出现大量的 TIME_WAIT。</p><blockquote><p>首先，我想说的是，没有必要见到两三万个 TIME_WAIT 就恐慌得不行。从内存的⻆度来考虑，一条 TIME_WAIT 状态的连接仅仅是 0.5 KB 的内存而已。从端口占用的角度来说，确实是消耗掉了一个端口。但假如你下次再连接的是不同的 Server 的话，该端口仍然可以使用。只有在所有 TIME_WAIT 都聚集在和一个 Server 的连接上的时候才会有问题。</p></blockquote><blockquote><p>那怎么解决呢? 其实办法有很多。第一个办法是按上面建议开启端口 reuse 和 recycle。 第二个办法是限制 TIME_WAIT 状态的连接的最大数量。</p></blockquote><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;"># vi /etc/sysctl.conf</span></span>
<span class="line"><span style="color:#FFCB6B;">net.ipv4.tcp_max_tw_buckets</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">32768</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># sysctl -p</span></span></code></pre></div><p>如果再彻底一些，也可以干脆直接用⻓连接代替频繁的短连接。连接频率大大降低以后，自然也就没有 TIME_WAIT 的问题了。好了，以上就是今天要给大家介绍的网络性能相关的 15 条建议，希望对大家有所帮助。</p><h1 id="终端操作快捷键" tabindex="-1">终端操作快捷键 <a class="header-anchor" href="#终端操作快捷键" aria-label="Permalink to &quot;终端操作快捷键&quot;">​</a></h1><p>作为一名 Linux 下的开发人员，和 Linux 系统打交道是每天必做的事情，通过 Linux 终端下命令行与 Linux 进行交互。熟练掌握 Linux 终端下命令行的操作可以让我们的工作达到事半功倍的效果，熟悉常用的终端命令快捷键可以很大程度上提高我们的工作效率。下面是平时常用的终端快捷键，希望小伙伴们熟练掌握，并灵活运用。</p><h2 id="_1、终端及标签页快捷键" tabindex="-1">1、终端及标签页快捷键 <a class="header-anchor" href="#_1、终端及标签页快捷键" aria-label="Permalink to &quot;1、终端及标签页快捷键&quot;">​</a></h2><table><thead><tr><th style="text-align:left;">快捷键</th><th style="text-align:left;">功能</th></tr></thead><tbody><tr><td style="text-align:left;">Shift+Ctrl+T</td><td style="text-align:left;">新建标签页</td></tr><tr><td style="text-align:left;">Shift+Ctrl+W</td><td style="text-align:left;">关闭标签页</td></tr><tr><td style="text-align:left;">Ctrl+PageUp</td><td style="text-align:left;">前一标签页</td></tr><tr><td style="text-align:left;">Ctrl+PageDown</td><td style="text-align:left;">后一标签页</td></tr><tr><td style="text-align:left;">Shift+Ctrl+PageUp</td><td style="text-align:left;">标签页左移</td></tr><tr><td style="text-align:left;">Shift+Ctrl+PageDown</td><td style="text-align:left;">标签页右移</td></tr><tr><td style="text-align:left;">Alt+1</td><td style="text-align:left;">切换到标签页1</td></tr><tr><td style="text-align:left;">Alt+2</td><td style="text-align:left;">切换到标签页2</td></tr><tr><td style="text-align:left;">Alt+3</td><td style="text-align:left;">切换到标签页3</td></tr><tr><td style="text-align:left;">Shift+Ctrl+N</td><td style="text-align:left;">新建窗口</td></tr><tr><td style="text-align:left;">Shift+Ctrl+Q</td><td style="text-align:left;">关闭终端</td></tr><tr><td style="text-align:left;">F11</td><td style="text-align:left;">全屏</td></tr><tr><td style="text-align:left;">Ctrl+Shift+加号</td><td style="text-align:left;">放大</td></tr><tr><td style="text-align:left;">Ctrl+减号</td><td style="text-align:left;">缩小</td></tr></tbody></table><h2 id="_2、剪切-复制-粘贴-删除等快捷键" tabindex="-1">2、剪切/复制/粘贴/删除等快捷键 <a class="header-anchor" href="#_2、剪切-复制-粘贴-删除等快捷键" aria-label="Permalink to &quot;2、剪切/复制/粘贴/删除等快捷键&quot;">​</a></h2><table><thead><tr><th style="text-align:left;">快捷键</th><th style="text-align:left;">功能</th></tr></thead><tbody><tr><td style="text-align:left;">Shift+Ctrl+C</td><td style="text-align:left;">复制</td></tr><tr><td style="text-align:left;">Shift+Ctrl+V</td><td style="text-align:left;">粘贴</td></tr><tr><td style="text-align:left;">Ctrl+Insert</td><td style="text-align:left;">复制命令行内容</td></tr><tr><td style="text-align:left;">Shift+Insert</td><td style="text-align:left;">粘贴命令行内容</td></tr><tr><td style="text-align:left;">Ctrl+k</td><td style="text-align:left;">剪切（删除）光标处到行尾的字符</td></tr><tr><td style="text-align:left;">Ctrl+u</td><td style="text-align:left;">剪切（删除）光标处到行首的字符</td></tr><tr><td style="text-align:left;">Ctrl+w</td><td style="text-align:left;">剪切（删除）光标前的一个单词</td></tr><tr><td style="text-align:left;">Ctrl+y</td><td style="text-align:left;">粘贴Ctrl+u，Ctrl+k，Ctrl+w删除的文本</td></tr><tr><td style="text-align:left;">Ctrl+c</td><td style="text-align:left;">中断终端正在执行的任务或者开始新命令输入行</td></tr><tr><td style="text-align:left;">Ctrl+h</td><td style="text-align:left;">删除光标所在处的前一个字符（相当于退格键）</td></tr><tr><td style="text-align:left;">Ctrl+l</td><td style="text-align:left;">清除屏幕所有内容，同clear命令</td></tr><tr><td style="text-align:left;">Ctrl+s</td><td style="text-align:left;">锁定终端，使之无法输入内容</td></tr><tr><td style="text-align:left;">Ctrl+q</td><td style="text-align:left;">解锁执行Ctrl+s的锁定状态</td></tr><tr><td style="text-align:left;">Ctrl+z</td><td style="text-align:left;">暂停执行在终端运行的任务</td></tr></tbody></table><h2 id="_3、移动光标快捷键" tabindex="-1">3、移动光标快捷键 <a class="header-anchor" href="#_3、移动光标快捷键" aria-label="Permalink to &quot;3、移动光标快捷键&quot;">​</a></h2><table><thead><tr><th style="text-align:left;">快捷键</th><th style="text-align:left;">功能</th></tr></thead><tbody><tr><td style="text-align:left;">Ctrl+a</td><td style="text-align:left;">移到行首</td></tr><tr><td style="text-align:left;">Ctrl+e</td><td style="text-align:left;">移到行尾</td></tr><tr><td style="text-align:left;">Ctrl+b</td><td style="text-align:left;">往回(左)移动一个字符</td></tr><tr><td style="text-align:left;">Ctrl+f</td><td style="text-align:left;">往后(右)移动一个字符</td></tr><tr><td style="text-align:left;">Alt+b</td><td style="text-align:left;">往回(左)移动一个单词</td></tr><tr><td style="text-align:left;">Alt+f</td><td style="text-align:left;">往后(右)移动一个单词</td></tr><tr><td style="text-align:left;">Ctrl+xx</td><td style="text-align:left;">在命令行尾和光标之间移动</td></tr></tbody></table><h2 id="_4、历史命令快捷键" tabindex="-1">4、历史命令快捷键 <a class="header-anchor" href="#_4、历史命令快捷键" aria-label="Permalink to &quot;4、历史命令快捷键&quot;">​</a></h2><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305111658510.png" alt="image-20230511165828407" style="zoom:67%;"><h2 id="_5、控制命令" tabindex="-1">5、控制命令 <a class="header-anchor" href="#_5、控制命令" aria-label="Permalink to &quot;5、控制命令&quot;">​</a></h2><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305111658947.png" alt="image-20230511165806854" style="zoom:80%;"><h1 id="linux-实用运维脚本" tabindex="-1">Linux 实用运维脚本 <a class="header-anchor" href="#linux-实用运维脚本" aria-label="Permalink to &quot;Linux 实用运维脚本&quot;">​</a></h1><p><a href="https://mp.weixin.qq.com/s?__biz=MzAwMjg1NjY3Nw==&amp;mid=2247528432&amp;idx=1&amp;sn=1d91bd1a80fcf1f1f8855316fb72e2d4&amp;chksm=9ac62c7aadb1a56c790006287b61336b50fa9833b2e68382cd331c228ee21350429a118d46a4&amp;scene=132#wechat_redirect" target="_blank" rel="noreferrer">Linux 实用运维脚本分享 (qq.com)</a></p><h2 id="简单命令" tabindex="-1">简单命令 <a class="header-anchor" href="#简单命令" aria-label="Permalink to &quot;简单命令&quot;">​</a></h2><div class="language-apl"><button title="Copy Code" class="copy"></button><span class="lang">apl</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">查看僵尸进程</span></span>
<span class="line"><span style="color:#A6ACCD;">ps </span><span style="color:#89DDFF;">-</span><span style="color:#A6ACCD;">al </span><span style="color:#89DDFF;">|</span><span style="color:#A6ACCD;"> gawk </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">{print $2,$4}</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">|</span><span style="color:#A6ACCD;"> grep Z</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;"> 匹配电子邮件的地址</span></span>
<span class="line"><span style="color:#A6ACCD;">cat index</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">html </span><span style="color:#89DDFF;">|</span><span style="color:#A6ACCD;"> egrep </span><span style="color:#89DDFF;">-</span><span style="color:#A6ACCD;">o </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">[A-Za-z0-9._]+@[A-Za-z0-9.]+\.[a-zA-Z]{2,4}</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> ans</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">txt</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">匹配http URL</span></span>
<span class="line"><span style="color:#A6ACCD;">cat index</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">html </span><span style="color:#89DDFF;">|</span><span style="color:#A6ACCD;"> egrep </span><span style="color:#89DDFF;">-</span><span style="color:#A6ACCD;">o </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">http://[A-Za-z0-9.]+\.[a-zA-Z]{2,3}</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> ans</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">txt </span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">纯文本形式下载网页</span></span>
<span class="line"><span style="color:#A6ACCD;">lynx </span><span style="color:#89DDFF;">-</span><span style="color:#A6ACCD;">dump www</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">baidu</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">com </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> plain</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">txt</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">只打印HTTP头部信息，无须远程下载文件</span></span>
<span class="line"><span style="color:#A6ACCD;">curl </span><span style="color:#89DDFF;">--</span><span style="color:#A6ACCD;">head www</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">baidu</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">com</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">使用POST提交数据</span></span>
<span class="line"><span style="color:#A6ACCD;">curl </span><span style="color:#89DDFF;">-</span><span style="color:#A6ACCD;">d </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">param2=nickwolfe¶m2=12345</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> http:</span><span style="color:#89DDFF;">//</span><span style="color:#A6ACCD;">www</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">linuxidc</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">com</span><span style="color:#89DDFF;">/</span><span style="color:#A6ACCD;">login</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">cgi</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">显示分组途经的网关</span></span>
<span class="line"><span style="color:#A6ACCD;">traceroute www</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">baidu</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">com</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">列出系统中的开放端口以及运行在端口上的服务</span></span>
<span class="line"><span style="color:#A6ACCD;">lsof </span><span style="color:#89DDFF;">-</span><span style="color:#A6ACCD;">i </span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">nc命令建立socket连接</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">设置监听　nc </span><span style="color:#89DDFF;">-</span><span style="color:#A6ACCD;">l </span><span style="color:#F78C6C;">5555</span></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">连接到套接字 nc </span><span style="color:#F78C6C;">192.0.0.1</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">5555</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">快速文件传输</span></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">接收端　nc </span><span style="color:#89DDFF;">-</span><span style="color:#A6ACCD;">l </span><span style="color:#F78C6C;">5555</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> destination_filename</span></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">发送端　nc </span><span style="color:#F78C6C;">192.0.0.1</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">5555</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;</span><span style="color:#A6ACCD;"> source_filename</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">找出指定目录最大的n个文件</span></span>
<span class="line"><span style="color:#A6ACCD;">du </span><span style="color:#89DDFF;">-</span><span style="color:#A6ACCD;">ak target_dir </span><span style="color:#89DDFF;">|</span><span style="color:#A6ACCD;"> sort </span><span style="color:#89DDFF;">-</span><span style="color:#A6ACCD;">nrk </span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">|</span><span style="color:#A6ACCD;"> head </span><span style="color:#89DDFF;">-</span><span style="color:#A6ACCD;">n </span><span style="color:#F78C6C;">4</span></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;"> du中a为递归</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">k为kb；sort中n为数字</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">r为降序</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">k指定列</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">向终端中的所有登陆用户发送广播信息</span></span>
<span class="line"><span style="color:#A6ACCD;">cat message</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">txt </span><span style="color:#89DDFF;">|</span><span style="color:#A6ACCD;"> wall</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">创建新的screen窗口</span></span>
<span class="line"><span style="color:#A6ACCD;">screen</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">打印所有的</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">txt和</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">pdf文件</span></span>
<span class="line"><span style="color:#A6ACCD;">find </span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">\(</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-</span><span style="color:#A6ACCD;">name </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">*.txt</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-</span><span style="color:#A6ACCD;">o </span><span style="color:#89DDFF;">-</span><span style="color:#A6ACCD;">name </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">*.pdf</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">\)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-</span><span style="color:#A6ACCD;">print</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-</span><span style="color:#A6ACCD;">exec command </span><span style="color:#89DDFF;">{}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">\;</span><span style="color:#A6ACCD;">是连用的，所有符合的都会放置在</span><span style="color:#89DDFF;">{}</span><span style="color:#A6ACCD;">中，去执行command </span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">将文件分割成多个大小为</span><span style="color:#F78C6C;">10kb</span><span style="color:#A6ACCD;">的文件</span></span>
<span class="line"><span style="color:#A6ACCD;">split </span><span style="color:#89DDFF;">-</span><span style="color:#A6ACCD;">b </span><span style="color:#F78C6C;">10k</span><span style="color:#A6ACCD;"> data</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">file </span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">打印两个文件的交集</span></span>
<span class="line"><span style="color:#A6ACCD;">comm A</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">txt B</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">txt </span><span style="color:#89DDFF;">-</span><span style="color:#F78C6C;">3</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">|</span><span style="color:#A6ACCD;"> sed </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">s/^\t//</span><span style="color:#89DDFF;">&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">#</span><span style="color:#A6ACCD;">sed移除空白行</span></span>
<span class="line"><span style="color:#A6ACCD;">sed </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">/^$/d</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;"> file</span></span></code></pre></div><h2 id="mysql备份" tabindex="-1">MySQL备份 <a class="header-anchor" href="#mysql备份" aria-label="Permalink to &quot;MySQL备份&quot;">​</a></h2><div class="language-shell"><button title="Copy Code" class="copy"></button><span class="lang">shell</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">#!/bin/bash</span></span>
<span class="line"><span style="color:#82AAFF;">set</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-e</span></span>
<span class="line"><span style="color:#A6ACCD;">USER</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">root</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">PASSWORD</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">123456</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 数据库数据目录 #</span></span>
<span class="line"><span style="color:#A6ACCD;">DATA_DIR</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/data/mysql</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">BIN_INDEX</span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;">$DATA_DIR</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/mysql-bin.index</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 备份目录 #</span></span>
<span class="line"><span style="color:#A6ACCD;">BACKUP_DIR</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/data/backup/mysql</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">BACKUP_LOG</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/var/log/mysql/backup.log</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">DATE</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">`</span><span style="color:#FFCB6B;">date</span><span style="color:#C3E88D;"> +</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">%Y%m%d</span><span style="color:#89DDFF;">&quot;`</span></span>
<span class="line"><span style="color:#A6ACCD;">TIME</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">`</span><span style="color:#FFCB6B;">date</span><span style="color:#C3E88D;"> +</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">%Y%m%d%H</span><span style="color:#89DDFF;">&quot;`</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">LOG_TIME</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">`</span><span style="color:#FFCB6B;">date</span><span style="color:#C3E88D;"> +</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">%Y-%m-%d %H:%M:%S</span><span style="color:#89DDFF;">&quot;`</span></span>
<span class="line"><span style="color:#A6ACCD;">DELETE_BINLOG_TIME</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">7 day</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">INCREMENT_INTERVAL</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">3 hour</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">note</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">[</span><span style="color:#A6ACCD;">$LOG_TIME</span><span style="color:#C3E88D;">] note: </span><span style="color:#A6ACCD;">$*</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&gt;&gt;</span><span style="color:#A6ACCD;"> $BACKUP_LOG</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">warning</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">[</span><span style="color:#A6ACCD;">$LOG_TIME</span><span style="color:#C3E88D;">] warning: </span><span style="color:#A6ACCD;">$*</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&gt;&gt;</span><span style="color:#A6ACCD;"> $BACKUP_LOG</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">error</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">[</span><span style="color:#A6ACCD;">$LOG_TIME</span><span style="color:#C3E88D;">] error: </span><span style="color:#A6ACCD;">$*</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&gt;&gt;</span><span style="color:#A6ACCD;"> $BACKUP_LOG</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#82AAFF;">exit</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">full_backup</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">local</span><span style="color:#A6ACCD;"> dbs</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">`</span><span style="color:#FFCB6B;">ls</span><span style="color:#C3E88D;"> -l </span><span style="color:#A6ACCD;">$DATA_DIR</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">grep</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">^d</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">awk</span><span style="color:#C3E88D;"> -F </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">{print $9}</span><span style="color:#89DDFF;">&#39;`</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">for</span><span style="color:#A6ACCD;"> db </span><span style="color:#89DDFF;font-style:italic;">in</span><span style="color:#A6ACCD;"> $dbs</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">do</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">local</span><span style="color:#A6ACCD;"> backup_dir</span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;">$BACKUP_DIR</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/full/</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">$db</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">local</span><span style="color:#A6ACCD;"> filename</span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;">$db</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">$DATE</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">local</span><span style="color:#A6ACCD;"> backup_file</span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;">$backup_dir</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">$filename</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.sql</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">!</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-d</span><span style="color:#A6ACCD;"> $backup_dir </span><span style="color:#89DDFF;">]</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">then</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#FFCB6B;">mkdir</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-p</span><span style="color:#A6ACCD;"> $backup_dir </span><span style="color:#89DDFF;">||</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">error</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">创建数据库 </span><span style="color:#A6ACCD;">$db</span><span style="color:#C3E88D;"> 全量备份目录 </span><span style="color:#A6ACCD;">$backup_dir</span><span style="color:#C3E88D;"> 失败</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#FFCB6B;">continue</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#FFCB6B;">note</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">数据库 </span><span style="color:#A6ACCD;">$db</span><span style="color:#C3E88D;"> 全量备份目录 </span><span style="color:#A6ACCD;">$backup_dir</span><span style="color:#C3E88D;">  不存在，创建完成</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">note</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">full backup </span><span style="color:#A6ACCD;">$db</span><span style="color:#C3E88D;"> start ...</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">mysqldump</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--user=</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">USER</span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--password=</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">PASSWORD</span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--flush-logs</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--skip-lock-tables</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--quick</span><span style="color:#A6ACCD;"> $db </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> $backup_file </span><span style="color:#89DDFF;">||</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">warning</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">数据库 </span><span style="color:#A6ACCD;">$db</span><span style="color:#C3E88D;"> 备份失败</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">continue</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#82AAFF;">cd</span><span style="color:#A6ACCD;"> $backup_dir</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">tar</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-cPzf</span><span style="color:#A6ACCD;"> $filename</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.tar.gz</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> $filename</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.sql</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">rm</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-f</span><span style="color:#A6ACCD;"> $backup_file</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">chown</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-fR</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">mysql:mysql</span><span style="color:#A6ACCD;"> $backup_dir</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">note</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">数据库 </span><span style="color:#A6ACCD;">$db</span><span style="color:#C3E88D;"> 备份成功</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">note</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">full backup </span><span style="color:#A6ACCD;">$db</span><span style="color:#C3E88D;"> end.</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">done</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">increment_backup</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">local</span><span style="color:#A6ACCD;"> StartTime</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">`</span><span style="color:#FFCB6B;">date</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">-d </span><span style="color:#A6ACCD;">$INCREMENT_INTERVAL</span><span style="color:#C3E88D;"> ago</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> +</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">%Y-%m-%d %H:%M:%S</span><span style="color:#89DDFF;">&quot;`</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">local</span><span style="color:#A6ACCD;"> DELETE_BINLOG_END_TIME</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">`</span><span style="color:#FFCB6B;">date</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">-d </span><span style="color:#A6ACCD;">$DELETE_BINLOG_TIME</span><span style="color:#C3E88D;"> ago</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> +</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">%Y-%m-%d %H:%M:%S</span><span style="color:#89DDFF;">&quot;`</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">local</span><span style="color:#A6ACCD;"> dbs</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">`</span><span style="color:#FFCB6B;">ls</span><span style="color:#C3E88D;"> -l </span><span style="color:#A6ACCD;">$DATA_DIR</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">grep</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">^d</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">awk</span><span style="color:#C3E88D;"> -F </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">{print $9}</span><span style="color:#89DDFF;">&#39;`</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#FFCB6B;">mysql</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-u</span><span style="color:#A6ACCD;">$USER</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-p</span><span style="color:#A6ACCD;">$PASSWORD</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-e</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">purge master logs before &#39;</span><span style="color:#A6ACCD;">$DELETE_BINLOG_END_TIME</span><span style="color:#C3E88D;">&#39;</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">note</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">delete </span><span style="color:#A6ACCD;">$DELETE_BINLOG_TIME</span><span style="color:#C3E88D;"> days before log</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    filename</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">`</span><span style="color:#FFCB6B;">cat</span><span style="color:#C3E88D;"> </span><span style="color:#A6ACCD;">$BIN_INDEX</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">awk</span><span style="color:#C3E88D;"> -F </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">{print $2}</span><span style="color:#89DDFF;">&#39;`</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">for</span><span style="color:#A6ACCD;"> i </span><span style="color:#89DDFF;font-style:italic;">in</span><span style="color:#A6ACCD;"> $filename</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">do</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">for</span><span style="color:#A6ACCD;"> db </span><span style="color:#89DDFF;font-style:italic;">in</span><span style="color:#A6ACCD;"> $dbs</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">do</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#C792EA;">local</span><span style="color:#A6ACCD;"> backup_dir</span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;">$BACKUP_DIR</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/increment/</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">$db</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#C792EA;">local</span><span style="color:#A6ACCD;"> filename</span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;">$db</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">$TIME</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#C792EA;">local</span><span style="color:#A6ACCD;"> backup_file</span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;">$backup_dir</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">$filename</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.sql</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">!</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-d</span><span style="color:#A6ACCD;"> $backup_dir </span><span style="color:#89DDFF;">]</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">then</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#FFCB6B;">mkdir</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-p</span><span style="color:#A6ACCD;"> $backup_dir </span><span style="color:#89DDFF;">||</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">error</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">创建数据库 </span><span style="color:#A6ACCD;">$db</span><span style="color:#C3E88D;"> 增量备份目录 </span><span style="color:#A6ACCD;">$backup_dir</span><span style="color:#C3E88D;"> 失败</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">continue</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">                </span><span style="color:#FFCB6B;">note</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">数据库 </span><span style="color:#A6ACCD;">$db</span><span style="color:#C3E88D;"> 增量备份目录 </span><span style="color:#A6ACCD;">$backup_dir</span><span style="color:#C3E88D;">  不存在，创建完成</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#89DDFF;font-style:italic;">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#FFCB6B;">note</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">increment backup </span><span style="color:#A6ACCD;">$db</span><span style="color:#C3E88D;"> form time </span><span style="color:#A6ACCD;">$StartTime</span><span style="color:#C3E88D;"> start ...</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#FFCB6B;">mysqlbinlog</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-d</span><span style="color:#A6ACCD;"> $db </span><span style="color:#C3E88D;">--start-datetime=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">$StartTime</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> $DATA_DIR</span><span style="color:#C3E88D;">/</span><span style="color:#A6ACCD;">$i </span><span style="color:#89DDFF;">&gt;&gt;</span><span style="color:#A6ACCD;"> $backup_file </span><span style="color:#89DDFF;">||</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">warning</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">数据库 </span><span style="color:#A6ACCD;">$db</span><span style="color:#C3E88D;"> 备份失败</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">continue</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">            </span><span style="color:#FFCB6B;">note</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">increment backup </span><span style="color:#A6ACCD;">$db</span><span style="color:#C3E88D;"> end.</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#89DDFF;font-style:italic;">done</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">done</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">for</span><span style="color:#A6ACCD;"> db </span><span style="color:#89DDFF;font-style:italic;">in</span><span style="color:#A6ACCD;"> $dbs</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">do</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">local</span><span style="color:#A6ACCD;"> backup_dir</span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;">$BACKUP_DIR</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/increment/</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">$db</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">local</span><span style="color:#A6ACCD;"> filename</span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;">$db</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">$TIME</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#C792EA;">local</span><span style="color:#A6ACCD;"> backup_file</span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;">$backup_dir</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">$filename</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.sql</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#82AAFF;">cd</span><span style="color:#A6ACCD;"> $backup_dir</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">tar</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-cPzf</span><span style="color:#A6ACCD;"> $filename</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.tar.gz</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> $filename</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.sql</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">rm</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-f</span><span style="color:#A6ACCD;"> $backup_file</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">note</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">数据库 </span><span style="color:#A6ACCD;">$db</span><span style="color:#C3E88D;"> 备份成功</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">done</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">case</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;font-style:italic;">$1</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">in</span></span>
<span class="line"><span style="color:#A6ACCD;">    full</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">full_backup</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">;;</span></span>
<span class="line"><span style="color:#A6ACCD;">    increment</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">increment_backup</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">;;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">*)</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#82AAFF;">exit</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">;;</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">esac</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">exit</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span></span></code></pre></div><h2 id="目录备份" tabindex="-1">目录备份 <a class="header-anchor" href="#目录备份" aria-label="Permalink to &quot;目录备份&quot;">​</a></h2><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">#!/bin/bash</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 时间</span></span>
<span class="line"><span style="color:#A6ACCD;">DATE</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">date</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">+%Y-%m-%d_%H_%M_%S</span><span style="color:#89DDFF;">&#39;)</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 备份目录 </span></span>
<span class="line"><span style="color:#A6ACCD;">BACKUPDIR</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">/home/backups</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 需要备份的目录</span></span>
<span class="line"><span style="color:#A6ACCD;">SORFILE</span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;">/opt</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 目标文件名</span></span>
<span class="line"><span style="color:#A6ACCD;">DESFILE</span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;">/home/backups/</span><span style="color:#A6ACCD;">$SORFILE</span><span style="color:#C3E88D;">.</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">date</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">+%Y-%m-%d_%H_%M_%S</span><span style="color:#89DDFF;">&#39;)</span><span style="color:#C3E88D;">.zip</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">!</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-d</span><span style="color:#A6ACCD;"> $BACKUPDIR </span><span style="color:#89DDFF;">]</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">mkdir</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-p</span><span style="color:#A6ACCD;"> $BACKUPDIR</span></span>
<span class="line"><span style="color:#82AAFF;">cd</span><span style="color:#A6ACCD;"> $BACKUPDIR</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">start backup </span><span style="color:#A6ACCD;">$SORFILE</span><span style="color:#C3E88D;"> ...</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">sleep</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#echo &quot;$DESFILE&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#tar cvf $DESFILE $SORFILE</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#gzip -f .zip $DESFILE</span></span>
<span class="line"><span style="color:#FFCB6B;">zip</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-r</span><span style="color:#A6ACCD;"> $DESFILE $SORFILE </span><span style="color:#89DDFF;">&amp;&gt;</span><span style="color:#A6ACCD;">/dev/null</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">$?</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">==</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">0</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">]</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">then</span></span>
<span class="line"><span style="color:#A6ACCD;">   </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">date</span><span style="color:#C3E88D;"> +%Y-%m-%d</span><span style="color:#89DDFF;">)&quot;</span><span style="color:#C3E88D;"> zip sucess</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">&gt;&gt;</span><span style="color:#C3E88D;">backup.log</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">else</span></span>
<span class="line"><span style="color:#A6ACCD;">   </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">date</span><span style="color:#C3E88D;"> +%Y-%m-%d</span><span style="color:#89DDFF;">)&quot;</span><span style="color:#C3E88D;"> zip failed</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">&gt;&gt;</span><span style="color:#C3E88D;">backup.log</span></span>
<span class="line"><span style="color:#A6ACCD;">   </span><span style="color:#82AAFF;">exit</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 删除3天前的备份</span></span>
<span class="line"><span style="color:#FFCB6B;">find</span><span style="color:#A6ACCD;"> $BACKUPDIR </span><span style="color:#C3E88D;">-type</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">f</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-ctime</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">+3</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">|</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">xargs</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">rm</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-rf</span></span></code></pre></div><h2 id="ping查询" tabindex="-1">PING查询 <a class="header-anchor" href="#ping查询" aria-label="Permalink to &quot;PING查询&quot;">​</a></h2><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">#!/bin/bash</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#用途：根据网络配置对网络地址192.168.0进行修改，检查是否是活动状态</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#{start..end}shell扩展生成一组地址</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">for</span><span style="color:#A6ACCD;"> ip </span><span style="color:#89DDFF;font-style:italic;">in</span><span style="color:#A6ACCD;"> 192.168.22.{</span><span style="color:#FFCB6B;">1..255}</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">do</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">(</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#FFCB6B;">ping</span><span style="color:#A6ACCD;"> $ip </span><span style="color:#C3E88D;">-c</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&amp;&gt;</span><span style="color:#A6ACCD;"> /dev/null </span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;"># &gt; 标准输出重定向，和1&gt;一致</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;"># 2&gt;&amp;1 将标准错误输出　重定向　到标准输出</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#676E95;font-style:italic;"># &amp;&gt;file 将标准输出和标准错误输出都重定向到文件filename中</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;"> $? </span><span style="color:#89DDFF;">-eq</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">];</span><span style="color:#89DDFF;font-style:italic;">then</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> $ip </span><span style="color:#C3E88D;">is</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">alive</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">fi</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;">)&amp;</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">done</span></span>
<span class="line"><span style="color:#82AAFF;">wait</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#并行ping,加速</span></span></code></pre></div><h2 id="磁盘io检查" tabindex="-1">磁盘IO检查 <a class="header-anchor" href="#磁盘io检查" aria-label="Permalink to &quot;磁盘IO检查&quot;">​</a></h2><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">##iostat是查看磁盘活动统计情况</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##显示所有设备负载情况 r/s:  每秒完成的读 I/O 设备次数。即 rio/s；w/s:  每秒完成的写 I/O 设备次数。即 wio/s等</span></span>
<span class="line"><span style="color:#FFCB6B;">iostat</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##每隔2秒刷新磁盘IO信息，并且每次显示3次</span></span>
<span class="line"><span style="color:#FFCB6B;">iostat</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#显示某个磁盘的IO信息</span></span>
<span class="line"><span style="color:#FFCB6B;">iostat</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-d</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">sda1</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##显示tty和cpu信息</span></span>
<span class="line"><span style="color:#FFCB6B;">iostat</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-t</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##以M为单位显示磁盘IO信息</span></span>
<span class="line"><span style="color:#FFCB6B;">iostat</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-m</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##查看TPS和吞吐量信息  kB_read/s：每秒从设备（drive expressed）读取的数据量；kB_wrtn/s：每秒向设备（drive expressed）写入的数据量；kB_read：读取的总数据量；kB_wrtn：写入的总数量数据量；</span></span>
<span class="line"><span style="color:#FFCB6B;">iostat</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-d</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-k</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#查看设备使用率（%util）、响应时间（await）</span></span>
<span class="line"><span style="color:#FFCB6B;">iostat</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-d</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-x</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-k</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#查看CPU状态</span></span>
<span class="line"><span style="color:#FFCB6B;">iostat</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-c</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#统计进程(pid)的stat,进程的stat自然包括进程的IO状况</span></span>
<span class="line"><span style="color:#FFCB6B;">pidstat</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#只显示IO</span></span>
<span class="line"><span style="color:#FFCB6B;">pidstat</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-d</span><span style="color:#A6ACCD;">  </span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#-d IO 信息,-r 缺页及内存信息-u CPU使用率-t 以线程为统计单位1  1秒统计一次</span></span>
<span class="line"><span style="color:#FFCB6B;">pidstat</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-u</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-r</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-d</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-t</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#文件级IO分析,查看当前文件由哪些进程打开</span></span>
<span class="line"><span style="color:#FFCB6B;">lsof</span><span style="color:#A6ACCD;">   </span></span>
<span class="line"><span style="color:#FFCB6B;">ls</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">/proc/pid/fd</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#利用 sar 报告磁盘 I/O 信息DEV 正在监视的块设备 tps 每秒钟物理设备的 I/O 传输总量 rd_sec/s 每秒从设备读取的扇区数量 wr_sec/s 每秒向设备写入的扇区数量 avgrq-sz I/O 请求的平均扇区数</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#avgqu-sz I/O 请求的平均队列长度 await I/O 请求的平均等待时间，单位为毫秒 svctm I/O 请求的平均服务时间，单位为毫秒 %util I/O 请求所占用的时间的百分比，即设备利用率</span></span>
<span class="line"><span style="color:#FFCB6B;">sar</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-pd</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">10</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#iotop  top的io版</span></span>
<span class="line"><span style="color:#FFCB6B;">iotop</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#查看页面缓存信息 其中的Cached 指用于pagecache的内存大小（diskcache-SwapCache）。随着写入缓存页，Dirty 的值会增加 一旦开始把缓存页写入硬盘,Writeback的值会增加直到写入结束。</span></span>
<span class="line"><span style="color:#FFCB6B;">cat</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">/proc/meminfo</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#查看有多少个pdflush进程 Linux 用pdflush进程把数据从缓存页写入硬盘</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#pdflush的行为受/proc/sys/vm中的参数的控制/proc/sys/vm/dirty_writeback_centisecs (default 500): 1/100秒, 多长时间唤醒pdflush将缓存页数据写入硬盘。默认5秒唤醒2个（更多个）线程。如果wrteback的时间长于dirty_writeback_centisecs的时间，可能会出问题</span></span>
<span class="line"><span style="color:#FFCB6B;">cat</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">/proc/sys/vm/nr_pdflush_threads</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#查看I/O 调度器</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#调度算法</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#noop anticipatory deadline [cfq] </span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#deadline :    deadline 算法保证对既定的IO请求以最小的延迟时间。</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#anticipatory：有个IO发生后，如果又有进程请求IO，则产生一个默认6ms猜测时间，猜测下一个进程请求IO是干什么。这对于随机读取会造成较大的延时。对数据库应用很糟糕，而对于Web Server等则会表现不错。</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#cfq:        对每个进程维护一个IO队列，各个进程发来的IO请求会被cfq以轮循方式处理，对每一个IO请求都是公平。适合离散读的应用。</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#noop:        对所有IO请求都用FIFO队列形式处理。默认IO不会存在性能问题。</span></span>
<span class="line"><span style="color:#FFCB6B;">cat</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">/sys/block/[disk]/queue/scheduler</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#改变IO调度器</span></span>
<span class="line"><span style="color:#FFCB6B;">$</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">deadline</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">/sys/block/sdX/queue/scheduler</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#提高调度器请求队列的</span></span>
<span class="line"><span style="color:#FFCB6B;">$</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">4096</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">/sys/block/sdX/queue/nr_requests</span></span></code></pre></div><h2 id="性能相关" tabindex="-1">性能相关 <a class="header-anchor" href="#性能相关" aria-label="Permalink to &quot;性能相关&quot;">​</a></h2><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">#查看当前系统load</span></span>
<span class="line"><span style="color:#FFCB6B;">uptime</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#查看系统状态和每个进程的系统资源使用状况</span></span>
<span class="line"><span style="color:#FFCB6B;">top</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#可视化显示CPU的使用状况</span></span>
<span class="line"><span style="color:#FFCB6B;">htop</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#查看每个CPU的负载信息</span></span>
<span class="line"><span style="color:#FFCB6B;">mpstat</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-P</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">ALL</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#每隔1秒查看磁盘IO的统计信息</span></span>
<span class="line"><span style="color:#FFCB6B;">iostat</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-xkdz</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#每隔一秒查看虚拟内存的使用信息</span></span>
<span class="line"><span style="color:#FFCB6B;">vmstat</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#查看内存使用统计信息</span></span>
<span class="line"><span style="color:#FFCB6B;">free</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#查看网络使用信息</span></span>
<span class="line"><span style="color:#FFCB6B;">nicstat</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-z</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#类似vmstat的显示优化的工具</span></span>
<span class="line"><span style="color:#FFCB6B;">dstat</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#查看系统活动状态，比如系统分页统计，块设备IO统计等</span></span>
<span class="line"><span style="color:#FFCB6B;">sar</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#网络连接状态查看</span></span>
<span class="line"><span style="color:#FFCB6B;">netstat</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-s</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#进程资源使用信息查看</span></span>
<span class="line"><span style="color:#FFCB6B;">pidstat</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span></span>
<span class="line"><span style="color:#FFCB6B;">pidstat</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-d</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#查看某个进程的系统调用信息 -p后面是进程id，-tttT 进程系统后的系统调用时间</span></span>
<span class="line"><span style="color:#FFCB6B;">strace</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-tttT</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-p</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">12670</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#统计IO设备输入输出的系统调用信息</span></span>
<span class="line"><span style="color:#FFCB6B;">strace</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-c</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">dd</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">if=/dev/zero</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">of=/dev/null</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">bs=</span><span style="color:#F78C6C;">512</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">count=</span><span style="color:#F78C6C;">1024</span><span style="color:#C3E88D;">k</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#tcpdump 查看网络数据包</span></span>
<span class="line"><span style="color:#FFCB6B;">tcpdump</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-nr</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">/tmp/out.tcpdump</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#块设备的读写事件信息统计</span></span>
<span class="line"><span style="color:#FFCB6B;">btrace</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">/dev/sdb</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#iotop查看某个进程的IO操作统计信息</span></span>
<span class="line"><span style="color:#FFCB6B;">iotop</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-bod5</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#slabtop 查看内核 slab内存分配器的使用信息</span></span>
<span class="line"><span style="color:#FFCB6B;">slabtop</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-sc</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#系统参数设置</span></span>
<span class="line"><span style="color:#FFCB6B;">sysctl</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-a</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#系统性能指标统计信息</span></span>
<span class="line"><span style="color:#FFCB6B;">perf</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">stat</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">gzip</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">file1</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#系统cpu活动状态查看</span></span>
<span class="line"><span style="color:#FFCB6B;">perf</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">record</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-a</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-g</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-F</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">997</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">sleep</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">10</span></span></code></pre></div><h2 id="进程相关" tabindex="-1">进程相关 <a class="header-anchor" href="#进程相关" aria-label="Permalink to &quot;进程相关&quot;">​</a></h2><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">## processes  进程管理</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##ps查看当前系统执行的线程列表，进行瞬间状态，不是连续状态，连续状态需要使用top名称查看  更多常用参数请使用 man ps查看</span></span>
<span class="line"><span style="color:#FFCB6B;">ps</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##显示所有进程详细信息</span></span>
<span class="line"><span style="color:#FFCB6B;">ps</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">aux</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##-u 显示某个用户的进程列表</span></span>
<span class="line"><span style="color:#FFCB6B;">ps</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-f</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-u</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">www-data</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">## -C 通过名字或者命令搜索进程</span></span>
<span class="line"><span style="color:#FFCB6B;">ps</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-C</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">apache2</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">## --sort  根据进程cpu使用率降序排列，查看前5个进程  -pcpu表示降序  pcpu升序</span></span>
<span class="line"><span style="color:#FFCB6B;">ps</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">aux</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--sort=-pcpu</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">|</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">head</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-5</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##-f 用树结构显示进程的层次关系，父子进程情况下</span></span>
<span class="line"><span style="color:#FFCB6B;">ps</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-f</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--forest</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-C</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">apache2</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##显示一个父进程的所有子进程</span></span>
<span class="line"><span style="color:#FFCB6B;">ps</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-o</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">pid,uname,comm</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-C</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">apache2</span></span>
<span class="line"><span style="color:#FFCB6B;">ps</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">--ppid</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2359</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##显示一个进程的所有线程  -L 参数</span></span>
<span class="line"><span style="color:#FFCB6B;">ps</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-p</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">3150</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-L</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##显示进程的执行时间 -o参数</span></span>
<span class="line"><span style="color:#FFCB6B;">ps</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-e</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-o</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">pid,comm,etime</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##watch命令可以用来实时捕捉ps显示进程</span></span>
<span class="line"><span style="color:#FFCB6B;">watch</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-n</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">ps -e -o pid,uname,cmd,pmem,pcpu --sort=-pmem,-pcpu | head -15</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##jobs 查看后台运行的进程  jobs命令执行的结果，＋表示是一个当前的作业，减号表是是一个当前作业之后的一个作业，jobs -l选项可显示所有任务的PID,jobs的状态可以是running, stopped, Terminated,但是如果任务被终止了（kill），shell 从当前的shell环境已知的列表中删除任务的进程标识；也就是说，jobs命令显示的是当前shell环境中所起的后台正在运行或者被挂起的任务信息</span></span>
<span class="line"><span style="color:#82AAFF;">jobs</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##查看后台运营的进程号</span></span>
<span class="line"><span style="color:#82AAFF;">jobs</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-p</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##查看现在被终止或者退出的进程号</span></span>
<span class="line"><span style="color:#82AAFF;">jobs</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-n</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##kill命令 终止一个前台进程可以使用Ctrl+C键   kill  通过top或者ps获取进程id号  kill [-s 信号 | -p ] [ -a ] 进程号 ...</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##发送指定的信号到相应进程。不指定型号将发送SIGTERM（15）终止指定进程。关闭进程号12的进程</span></span>
<span class="line"><span style="color:#82AAFF;">kill</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">12</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##等同于在前台运行PID为123的进程时按下Ctrl+C键</span></span>
<span class="line"><span style="color:#82AAFF;">kill</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-2</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">123</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##如果任无法终止该程序可用“-KILL” 参数，其发送的信号为SIGKILL(9) ，将强制结束进程  </span></span>
<span class="line"><span style="color:#82AAFF;">kill</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-9</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">123</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##列出所有信号名称</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##HUP    1    终端断线</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##INT     2    中断（同 Ctrl + C）</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##QUIT    3    退出（同 Ctrl + \）</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##TERM   15    终止</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##KILL    9    强制终止</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##CONT   18    继续（与STOP相反， fg/bg命令）</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##STOP    19    暂停（同 Ctrl + Z）</span></span>
<span class="line"><span style="color:#82AAFF;">kill</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-l</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##得到指定信号的数值</span></span>
<span class="line"><span style="color:#82AAFF;">kill</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-l</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">KILL</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##杀死指定用户所有进程</span></span>
<span class="line"><span style="color:#82AAFF;">kill</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-u</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">peidalinux</span></span>
<span class="line"><span style="color:#82AAFF;">kill</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-9</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">ps</span><span style="color:#C3E88D;"> -ef </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">grep</span><span style="color:#C3E88D;"> peidalinux</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##将后台中的命令调至前台继续运行  将进程123调至前台执行</span></span>
<span class="line"><span style="color:#82AAFF;">fg</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">123</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##将一个在后台暂停的命令，变成继续执行</span></span>
<span class="line"><span style="color:#82AAFF;">bg</span><span style="color:#A6ACCD;">  </span><span style="color:#F78C6C;">123</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##该命令可以在你退出帐户/关闭终端之后继续运行相应的进程。nohup就是不挂起的意思  下面输出被重定向到myout.file文件中</span></span>
<span class="line"><span style="color:#FFCB6B;">nohup</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">command</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">myout.file</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">2&gt;&amp;1</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&amp;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##at：计划任务，在特定的时间执行某项工作，在特定的时间执行一次。</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">## 格式：at HH:MM YYYY-MM-DD //HH（小时）:MM（分钟） YYYY（年）-MM（月份）-DD（日）</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##HH[am pm]+D(天) days //HH（小时）[am（上午）pm（下午）]+days（天）</span></span>
<span class="line"><span style="color:#FFCB6B;">at</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">12</span><span style="color:#C3E88D;">:00（时间）</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">//at命令设定12:00执行一项操作</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#at&gt;useradd aaa //在at命令里设定添加用户aaa</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#ctrl+d //退出at命令</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#tail -f /etc/passwd //查看/etc/passwd文件后十行是否增加了一个用户aaa</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##计划任务设定后，在没有执行之前我们可以用atq命令来查看系统没有执行工作任务。</span></span>
<span class="line"><span style="color:#FFCB6B;">atq</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##启动计划任务后，如果不想启动设定好的计划任务可以使用atrm命令删除。</span></span>
<span class="line"><span style="color:#FFCB6B;">atrm</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">//删除计划任务1</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##pstree命令：列出当前的进程，以及它们的树状结构  格式：pstree [选项] [pid|user]</span></span>
<span class="line"><span style="color:#FFCB6B;">pstree</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##nice命令：改变程序执行的优先权等级 应用程序优先权值的范围从-20～19，数字越小，优先权就越高。一般情况下，普通应用程序的优先权值（CPU使用权值）都是0，如果让常用程序拥有较高的优先权等级，自然启动和运行速度都会快些。需要注意的是普通用户只能在0～19之间调整应用程序的优先权值，只有超级用户有权调整更高的优先权值（从-20～19）。</span></span>
<span class="line"><span style="color:#FFCB6B;">nice</span><span style="color:#A6ACCD;"> [-n </span><span style="color:#89DDFF;">&lt;</span><span style="color:#C3E88D;">优先等</span><span style="color:#A6ACCD;">级</span><span style="color:#89DDFF;">&gt;</span><span style="color:#C3E88D;">][--help][--version][命令]</span></span>
<span class="line"><span style="color:#FFCB6B;">nice</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-n</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">5</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">ls</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##sleep命令：使进程暂停执行一段时间</span></span>
<span class="line"><span style="color:#FFCB6B;">date</span><span style="color:#89DDFF;">;</span><span style="color:#FFCB6B;">sleep</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#C3E88D;">m</span><span style="color:#89DDFF;">;</span><span style="color:#FFCB6B;">date</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##renice命令 renice命令允许用户修改一个正在运行进程的优先权。利用renice命令可以在命令执行时调整其优先权。</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##其中，参数number与nice命令的number意义相同。（1） 用户只能对自己所有的进程使用renice命令。（2） root用户可以在任何进程上使用renice命令。（3） 只有root用户才能提高进程的优先权</span></span>
<span class="line"><span style="color:#FFCB6B;">renice</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-5</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-p</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">5200</span><span style="color:#A6ACCD;">  </span><span style="color:#676E95;font-style:italic;">#PID为5200的进程nice设为-5 </span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##pmap命令用于显示一个或多个进程的内存状态。其报告进程的地址空间和内存状态信息 #pmap PID </span></span>
<span class="line"><span style="color:#FFCB6B;">pmap</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">20367</span></span></code></pre></div><h2 id="javadump-sh" tabindex="-1">javadump.sh <a class="header-anchor" href="#javadump-sh" aria-label="Permalink to &quot;javadump.sh&quot;">​</a></h2><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">#!/bin/sh</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">DUMP_PIDS</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">`</span><span style="color:#FFCB6B;">ps</span><span style="color:#C3E88D;">  --no-heading -C java -f --width </span><span style="color:#F78C6C;">1000</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#FFCB6B;">awk</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">{print $2}</span><span style="color:#89DDFF;">&#39;`</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-z</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;">$DUMP_PIDS</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">];</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">then</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">The server </span><span style="color:#A6ACCD;">$HOST_NAME</span><span style="color:#C3E88D;"> is not started!</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#82AAFF;">exit</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">DUMP_ROOT</span><span style="color:#89DDFF;">=</span><span style="color:#C3E88D;">~/dump</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">!</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-d</span><span style="color:#A6ACCD;"> $DUMP_ROOT </span><span style="color:#89DDFF;">];</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">then</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">mkdir</span><span style="color:#A6ACCD;"> $DUMP_ROOT</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">DUMP_DATE</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">`</span><span style="color:#FFCB6B;">date</span><span style="color:#C3E88D;"> +%Y%m%d%H%M%S</span><span style="color:#89DDFF;">`</span></span>
<span class="line"><span style="color:#A6ACCD;">DUMP_DIR</span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;">$DUMP_ROOT</span><span style="color:#C3E88D;">/dump-</span><span style="color:#A6ACCD;">$DUMP_DATE</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">!</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-d</span><span style="color:#A6ACCD;"> $DUMP_DIR </span><span style="color:#89DDFF;">];</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">then</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">mkdir</span><span style="color:#A6ACCD;"> $DUMP_DIR</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">for</span><span style="color:#A6ACCD;"> PID </span><span style="color:#89DDFF;font-style:italic;">in</span><span style="color:#A6ACCD;"> $DUMP_PIDS </span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">do</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#Full thread dump 用来查线程占用，死锁等问题</span></span>
<span class="line"><span style="color:#A6ACCD;">  $JAVA_HOME/bin/jstack $PID </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> $DUMP_DIR</span><span style="color:#C3E88D;">/jstack-</span><span style="color:#A6ACCD;">$PID</span><span style="color:#C3E88D;">.dump</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">2&gt;&amp;1</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-e</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.\c</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#打印出一个给定的Java进程、Java core文件或远程Debug服务器的Java配置信息，具体包括Java系统属性和JVM命令行参数。</span></span>
<span class="line"><span style="color:#A6ACCD;">  $JAVA_HOME/bin/jinfo $PID </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> $DUMP_DIR</span><span style="color:#C3E88D;">/jinfo-</span><span style="color:#A6ACCD;">$PID</span><span style="color:#C3E88D;">.dump</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">2&gt;&amp;1</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-e</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.\c</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#jstat能够动态打印jvm(Java Virtual Machine Statistics Monitoring Tool)的相关统计信息。如young gc执行的次数、full gc执行的次数，各个内存分区的空间大小和可使用量等信息。</span></span>
<span class="line"><span style="color:#A6ACCD;">  $JAVA_HOME/bin/jstat </span><span style="color:#C3E88D;">-gcutil</span><span style="color:#A6ACCD;"> $PID </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> $DUMP_DIR</span><span style="color:#C3E88D;">/jstat-gcutil-</span><span style="color:#A6ACCD;">$PID</span><span style="color:#C3E88D;">.dump</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">2&gt;&amp;1</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-e</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.\c</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">  $JAVA_HOME/bin/jstat </span><span style="color:#C3E88D;">-gccapacity</span><span style="color:#A6ACCD;"> $PID </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> $DUMP_DIR</span><span style="color:#C3E88D;">/jstat-gccapacity-</span><span style="color:#A6ACCD;">$PID</span><span style="color:#C3E88D;">.dump</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">2&gt;&amp;1</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-e</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.\c</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#未指定选项时，jmap打印共享对象的映射。对每个目标VM加载的共享对象，其起始地址、映射大小及共享对象文件的完整路径将被打印出来，  </span></span>
<span class="line"><span style="color:#A6ACCD;">  $JAVA_HOME/bin/jmap $PID </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> $DUMP_DIR</span><span style="color:#C3E88D;">/jmap-</span><span style="color:#A6ACCD;">$PID</span><span style="color:#C3E88D;">.dump</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">2&gt;&amp;1</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-e</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.\c</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#-heap打印堆情况的概要信息，包括堆配置，各堆空间的容量、已使用和空闲情况  </span></span>
<span class="line"><span style="color:#A6ACCD;">  $JAVA_HOME/bin/jmap </span><span style="color:#C3E88D;">-heap</span><span style="color:#A6ACCD;"> $PID </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> $DUMP_DIR</span><span style="color:#C3E88D;">/jmap-heap-</span><span style="color:#A6ACCD;">$PID</span><span style="color:#C3E88D;">.dump</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">2&gt;&amp;1</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-e</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.\c</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#-dump将jvm的堆中内存信息输出到一个文件中,然后可以通过eclipse memory analyzer进行分析</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#注意：这个jmap使用的时候jvm是处在假死状态的，只能在服务瘫痪的时候为了解决问题来使用，否则会造成服务中断。</span></span>
<span class="line"><span style="color:#A6ACCD;">  $JAVA_HOME/bin/jmap </span><span style="color:#C3E88D;">-dump:format=b,file=</span><span style="color:#A6ACCD;">$DUMP_DIR</span><span style="color:#C3E88D;">/jmap-dump-</span><span style="color:#A6ACCD;">$PID</span><span style="color:#C3E88D;">.dump</span><span style="color:#A6ACCD;"> $PID </span><span style="color:#89DDFF;">2&gt;&amp;1</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-e</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.\c</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#显示被进程打开的文件信息</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-r</span><span style="color:#A6ACCD;"> /usr/sbin/lsof </span><span style="color:#89DDFF;">];</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">then</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">/usr/sbin/lsof</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-p</span><span style="color:#A6ACCD;"> $PID </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> $DUMP_DIR</span><span style="color:#C3E88D;">/lsof-</span><span style="color:#A6ACCD;">$PID</span><span style="color:#C3E88D;">.dump</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-e</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.\c</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;font-style:italic;">fi</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">done</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#主要负责收集、汇报与存储系统运行信息的。</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-r</span><span style="color:#A6ACCD;"> /usr/bin/sar </span><span style="color:#89DDFF;">];</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">then</span></span>
<span class="line"><span style="color:#FFCB6B;">/usr/bin/sar</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> $DUMP_DIR</span><span style="color:#C3E88D;">/sar.dump</span></span>
<span class="line"><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-e</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.\c</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">fi</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#主要负责收集、汇报与存储系统运行信息的。</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-r</span><span style="color:#A6ACCD;"> /usr/bin/uptime </span><span style="color:#89DDFF;">];</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">then</span></span>
<span class="line"><span style="color:#FFCB6B;">/usr/bin/uptime</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> $DUMP_DIR</span><span style="color:#C3E88D;">/uptime.dump</span></span>
<span class="line"><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-e</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.\c</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">fi</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#内存查看</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-r</span><span style="color:#A6ACCD;"> /usr/bin/free </span><span style="color:#89DDFF;">];</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">then</span></span>
<span class="line"><span style="color:#FFCB6B;">/usr/bin/free</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-t</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> $DUMP_DIR</span><span style="color:#C3E88D;">/free.dump</span></span>
<span class="line"><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-e</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.\c</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">fi</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#可以得到关于进程、内存、内存分页、堵塞IO、traps及CPU活动的信息。</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-r</span><span style="color:#A6ACCD;"> /usr/bin/vmstat </span><span style="color:#89DDFF;">];</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">then</span></span>
<span class="line"><span style="color:#FFCB6B;">/usr/bin/vmstat</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> $DUMP_DIR</span><span style="color:#C3E88D;">/vmstat.dump</span></span>
<span class="line"><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-e</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.\c</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">fi</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#报告与CPU相关的一些统计信息</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-r</span><span style="color:#A6ACCD;"> /usr/bin/mpstat </span><span style="color:#89DDFF;">];</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">then</span></span>
<span class="line"><span style="color:#FFCB6B;">/usr/bin/mpstat</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> $DUMP_DIR</span><span style="color:#C3E88D;">/mpstat.dump</span></span>
<span class="line"><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-e</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.\c</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">fi</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#报告与IO相关的一些统计信息</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-r</span><span style="color:#A6ACCD;"> /usr/bin/iostat </span><span style="color:#89DDFF;">];</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">then</span></span>
<span class="line"><span style="color:#FFCB6B;">/usr/bin/iostat</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> $DUMP_DIR</span><span style="color:#C3E88D;">/iostat.dump</span></span>
<span class="line"><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-e</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.\c</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">fi</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">#报告与网络相关的一些统计信息</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-r</span><span style="color:#A6ACCD;"> /bin/netstat </span><span style="color:#89DDFF;">];</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">then</span></span>
<span class="line"><span style="color:#FFCB6B;">/bin/netstat</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> $DUMP_DIR</span><span style="color:#C3E88D;">/netstat.dump</span></span>
<span class="line"><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-e</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.\c</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#89DDFF;font-style:italic;">fi</span></span>
<span class="line"><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">OK!</span><span style="color:#89DDFF;">&quot;</span></span></code></pre></div><h2 id="常用工具安装" tabindex="-1">常用工具安装 <a class="header-anchor" href="#常用工具安装" aria-label="Permalink to &quot;常用工具安装&quot;">​</a></h2><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">#!/usr/bin/env bash</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># ---------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 控制台颜色</span></span>
<span class="line"><span style="color:#A6ACCD;">BLACK</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;30m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">RED</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;31m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">GREEN</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;32m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">YELLOW</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;33m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">BLUE</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;34m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">PURPLE</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;35m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;36m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;$(</span><span style="color:#FFCB6B;">tput</span><span style="color:#C3E88D;"> sgr0</span><span style="color:#89DDFF;">)&quot;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># ---------------------------------------------------------------------------------</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;${</span><span style="color:#A6ACCD;">BLUE</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">cat</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#C3E88D;">###################################################################################</span></span>
<span class="line"><span style="color:#C3E88D;"># 安装常用命令工具</span></span>
<span class="line"><span style="color:#C3E88D;"># 命令工具清单如下：</span></span>
<span class="line"><span style="color:#C3E88D;"># 核心工具：df、du、chkconfig</span></span>
<span class="line"><span style="color:#C3E88D;"># 网络工具：ifconfig、netstat、route、iptables</span></span>
<span class="line"><span style="color:#C3E88D;"># IP工具：ip、ss、ping、tracepath、traceroute</span></span>
<span class="line"><span style="color:#C3E88D;"># DNS工具：dig、host、nslookup、whois</span></span>
<span class="line"><span style="color:#C3E88D;"># 端口工具：lsof、nc、telnet</span></span>
<span class="line"><span style="color:#C3E88D;"># 下载工具：curl、wget</span></span>
<span class="line"><span style="color:#C3E88D;"># 编辑工具：emacs、vim</span></span>
<span class="line"><span style="color:#C3E88D;"># 流量工具：iftop、nethogs</span></span>
<span class="line"><span style="color:#C3E88D;"># 抓包工具：tcpdump</span></span>
<span class="line"><span style="color:#C3E88D;"># 压缩工具：unzip、zip</span></span>
<span class="line"><span style="color:#C3E88D;"># 版本控制工具：git、subversion</span></span>
<span class="line"><span style="color:#C3E88D;">#</span></span>
<span class="line"><span style="color:#C3E88D;">###################################################################################</span></span>
<span class="line"><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">GREEN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; 安装常用命令工具开始</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 核心工具</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install coreutils(df、du)</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">coreutils</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install chkconfig</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">chkconfig</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 网络工具</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install net-tools(ifconfig、netstat、route)</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">net-tools</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install iptables</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">iptables</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># IP工具</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install iputils(ping、tracepath)</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">iputils</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install traceroute</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">traceroute</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install iproute(ip、ss)</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">iproute</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 端口工具</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install lsof</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">lsof</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install nc</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">nc</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install netstat</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">netstat</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># DNS工具</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install bind-utils(dig、host、nslookup)</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">bind-utils</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install whois</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">whois</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 下载工具</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install curl</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">curl</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install wget</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">wget</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 编辑工具</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install emacs</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">emacs</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install vim</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">vim</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 流量工具</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install iftop</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">iftop</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install nethogs</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">nethogs</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 抓包工具</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install tcpdump</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">tcpdump</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 压缩工具</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install unzip</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">unzip</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 版本控制工具</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install git</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">git</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install subversion</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">subversion</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">GREEN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; 安装常用命令工具结束</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span></code></pre></div><h2 id="常用lib库安装" tabindex="-1">常用lib库安装 <a class="header-anchor" href="#常用lib库安装" aria-label="Permalink to &quot;常用lib库安装&quot;">​</a></h2><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">#!/usr/bin/env bash</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># ---------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 控制台颜色</span></span>
<span class="line"><span style="color:#A6ACCD;">BLACK</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;30m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">RED</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;31m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">GREEN</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;32m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">YELLOW</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;33m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">BLUE</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;34m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">PURPLE</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;35m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;36m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;$(</span><span style="color:#FFCB6B;">tput</span><span style="color:#C3E88D;"> sgr0</span><span style="color:#89DDFF;">)&quot;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># ---------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;${</span><span style="color:#A6ACCD;">BLUE</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">cat</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#C3E88D;">###################################################################################</span></span>
<span class="line"><span style="color:#C3E88D;"># 安装常见 lib</span></span>
<span class="line"><span style="color:#C3E88D;"># 如果不知道命令在哪个 lib，可以使用 yum search xxx 来查找</span></span>
<span class="line"><span style="color:#C3E88D;"># lib 清单如下：</span></span>
<span class="line"><span style="color:#C3E88D;"># gcc gcc-c++ kernel-devel libtool</span></span>
<span class="line"><span style="color:#C3E88D;"># openssl openssl-devel</span></span>
<span class="line"><span style="color:#C3E88D;"># zlib zlib-devel</span></span>
<span class="line"><span style="color:#C3E88D;"># pcre</span></span>
<span class="line"><span style="color:#C3E88D;">###################################################################################</span></span>
<span class="line"><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">GREEN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; 安装常见 lib 开始</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install gcc gcc-c++ kernel-devel libtool</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">make</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">gcc</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">gcc-c++</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">kernel-devel</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">libtool</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install openssl openssl-devel</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">make</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">openssl</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">openssl-devel</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install zlib zlib-devel</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">make</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">zlib</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">zlib-devel</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">CYAN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&gt;&gt;&gt;&gt; install pcre</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">yum</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-y</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">install</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">pcre</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">GREEN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; 安装常见 lib 结束</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span></code></pre></div><h2 id="系统检查脚本-好用" tabindex="-1">系统检查脚本(好用) <a class="header-anchor" href="#系统检查脚本-好用" aria-label="Permalink to &quot;系统检查脚本(好用)&quot;">​</a></h2><div class="language-sh"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">#!/usr/bin/env bash</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##############################################################################</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># console color</span></span>
<span class="line"><span style="color:#A6ACCD;">C_RESET</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;$(</span><span style="color:#FFCB6B;">tput</span><span style="color:#C3E88D;"> sgr0</span><span style="color:#89DDFF;">)&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">C_BLACK</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;30m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">C_RED</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;31m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">C_GREEN</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;32m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">C_YELLOW</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;33m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">C_BLUE</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;34m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">C_PURPLE</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;35m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">C_CYAN</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;36m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">C_WHITE</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\033[1;37m</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#676E95;font-style:italic;">##############################################################################</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;${</span><span style="color:#A6ACCD;">C_PURPLE</span><span style="color:#89DDFF;">}&quot;</span></span>
<span class="line"><span style="color:#FFCB6B;">cat</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#C3E88D;">###################################################################################</span></span>
<span class="line"><span style="color:#C3E88D;"># 系统信息检查脚本</span></span>
<span class="line"><span style="color:#C3E88D;">###################################################################################</span></span>
<span class="line"><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;${</span><span style="color:#A6ACCD;">C_RESET</span><span style="color:#89DDFF;">}&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">[[</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">id</span><span style="color:#C3E88D;"> -u</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-gt</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">]]</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">请用root用户执行此脚本！</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">exit</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span></span>
<span class="line"><span style="color:#A6ACCD;">sysversion</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">rpm</span><span style="color:#C3E88D;"> -q centos-release </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">cut</span><span style="color:#C3E88D;"> -d- -f3</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">double_line</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">===============================================================</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">line</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">----------------------------------------------</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 打印头部信息</span></span>
<span class="line"><span style="color:#82AAFF;">printHeadInfo</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">cat</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#C3E88D;">+---------------------------------------------------------------------------------+</span></span>
<span class="line"><span style="color:#C3E88D;">|                           欢迎使用 【系统信息检查脚本】                          |</span></span>
<span class="line"><span style="color:#C3E88D;">+---------------------------------------------------------------------------------+</span></span>
<span class="line"><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 打印尾部信息</span></span>
<span class="line"><span style="color:#82AAFF;">printFootInfo</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">cat</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#C3E88D;">+---------------------------------------------------------------------------------+</span></span>
<span class="line"><span style="color:#C3E88D;">|                            脚本执行结束，感谢使用！|</span></span>
<span class="line"><span style="color:#C3E88D;">+---------------------------------------------------------------------------------+</span></span>
<span class="line"><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">options</span><span style="color:#89DDFF;">=(</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">获取系统信息</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">获取服务信息</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">获取CPU信息</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">获取系统网络信息</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">获取系统内存信息</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">获取系统磁盘信息</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">获取CPU/内存占用TOP10</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">获取系统用户信息</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">输出所有信息</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">退出</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#82AAFF;">printMenu</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;${</span><span style="color:#A6ACCD;">C_BLUE</span><span style="color:#89DDFF;">}&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">主菜单：\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;font-style:italic;">for</span><span style="color:#A6ACCD;"> i </span><span style="color:#89DDFF;font-style:italic;">in</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;${!</span><span style="color:#A6ACCD;">options</span><span style="color:#89DDFF;">[</span><span style="color:#C3E88D;">@</span><span style="color:#89DDFF;">]}&quot;</span><span style="color:#89DDFF;">;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">do</span></span>
<span class="line"><span style="color:#A6ACCD;">    index</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">`</span><span style="color:#FFCB6B;">expr</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">i</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;"> + </span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">`</span></span>
<span class="line"><span style="color:#A6ACCD;">    val</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">`</span><span style="color:#FFCB6B;">expr</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">index</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;"> % </span><span style="color:#F78C6C;">2</span><span style="color:#89DDFF;">`</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\t(%02d) %-30s</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;${</span><span style="color:#A6ACCD;">index</span><span style="color:#89DDFF;">}&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;${</span><span style="color:#A6ACCD;">options</span><span style="color:#89DDFF;">[</span><span style="color:#C3E88D;">$i</span><span style="color:#89DDFF;">]}&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[[</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">val</span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-eq</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">]];</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">then</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">fi</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;font-style:italic;">done</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;${</span><span style="color:#A6ACCD;">C_BLUE</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">请输入需要执行的指令：\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;${</span><span style="color:#A6ACCD;">C_RESET</span><span style="color:#89DDFF;">}&quot;</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 获取系统信息</span></span>
<span class="line"><span style="color:#82AAFF;">get_systatus_info</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  sys_os</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">uname</span><span style="color:#C3E88D;"> -o</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  sys_release</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">cat</span><span style="color:#C3E88D;"> /etc/redhat-release</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  sys_kernel</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">uname</span><span style="color:#C3E88D;"> -r</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  sys_hostname</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">hostname</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  sys_selinux</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">getenforce</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  sys_lang</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#82AAFF;">echo</span><span style="color:#C3E88D;"> </span><span style="color:#A6ACCD;">$LANG</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  sys_lastreboot</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">who</span><span style="color:#C3E88D;"> -b </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">awk</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">{print $3,$4}</span><span style="color:#89DDFF;">&#39;)</span></span>
<span class="line"><span style="color:#A6ACCD;">  sys_runtime</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">uptime</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">awk</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">{print  $3,$4}</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">cut</span><span style="color:#C3E88D;"> -d, -f1</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  sys_time</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">date</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  sys_load</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">uptime</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">cut</span><span style="color:#C3E88D;"> -d: -f5</span><span style="color:#89DDFF;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">cat</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#C3E88D;">【系统信息】</span></span>
<span class="line"><span style="color:#C3E88D;">系统: </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">sys_os</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">发行版本:   </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">sys_release</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">系统内核:   </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">sys_kernel</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">主机名:    </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">sys_hostname</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">selinux状态:  </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">sys_selinux</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">系统语言:   </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">sys_lang</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">系统当前时间: </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">sys_time</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">系统最后重启时间:   </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">sys_lastreboot</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">系统运行时间: </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">sys_runtime</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">系统负载:   </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">sys_load</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 获取CPU信息</span></span>
<span class="line"><span style="color:#82AAFF;">get_cpu_info</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  Physical_CPUs</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">grep</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">physical id</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> /proc/cpuinfo </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">sort</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">uniq</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">wc</span><span style="color:#C3E88D;"> -l</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  Virt_CPUs</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">grep</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">processor</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> /proc/cpuinfo </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">wc</span><span style="color:#C3E88D;"> -l</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  CPU_Kernels</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">grep</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">cores</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> /proc/cpuinfo </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">uniq</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">awk</span><span style="color:#C3E88D;"> -F </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">: </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">{print $2}</span><span style="color:#89DDFF;">&#39;)</span></span>
<span class="line"><span style="color:#A6ACCD;">  CPU_Type</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">grep</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">model name</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> /proc/cpuinfo </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">awk</span><span style="color:#C3E88D;"> -F </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">: </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">{print $2}</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">sort</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">uniq</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  CPU_Arch</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">uname</span><span style="color:#C3E88D;"> -m</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">cat</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#C3E88D;">【CPU信息】</span></span>
<span class="line"><span style="color:#C3E88D;">物理CPU个数:</span><span style="color:#A6ACCD;">$Physical_CPUs</span></span>
<span class="line"><span style="color:#C3E88D;">逻辑CPU个数:</span><span style="color:#A6ACCD;">$Virt_CPUs</span></span>
<span class="line"><span style="color:#C3E88D;">每CPU核心数:</span><span style="color:#A6ACCD;">$CPU_Kernels</span></span>
<span class="line"><span style="color:#C3E88D;">CPU型号:</span><span style="color:#A6ACCD;">$CPU_Type</span></span>
<span class="line"><span style="color:#C3E88D;">CPU架构:</span><span style="color:#A6ACCD;">$CPU_Arch</span></span>
<span class="line"><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 获取服务信息</span></span>
<span class="line"><span style="color:#82AAFF;">get_service_info</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  port_listen</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">netstat</span><span style="color:#C3E88D;"> -lntup </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">grep</span><span style="color:#C3E88D;"> -v </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">Active Internet</span><span style="color:#89DDFF;">&quot;)</span></span>
<span class="line"><span style="color:#A6ACCD;">  kernel_config</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">sysctl</span><span style="color:#C3E88D;"> -p </span><span style="color:#89DDFF;">2&gt;</span><span style="color:#C3E88D;"> /dev/null</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[[</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">sysversion</span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">-gt</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">6</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">]];</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">then</span></span>
<span class="line"><span style="color:#A6ACCD;">    service_config</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">systemctl</span><span style="color:#C3E88D;"> list-unit-files --type=service --state=enabled </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">grep</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">enabled</span><span style="color:#89DDFF;">&quot;)</span></span>
<span class="line"><span style="color:#A6ACCD;">    run_service</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">systemctl</span><span style="color:#C3E88D;"> list-units --type=service --state=running </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">grep</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">.service</span><span style="color:#89DDFF;">&quot;)</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;font-style:italic;">else</span></span>
<span class="line"><span style="color:#A6ACCD;">    service_config</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">/sbin/chkconfig</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">grep</span><span style="color:#C3E88D;"> -E </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">:on|:启用</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">column</span><span style="color:#C3E88D;"> -t</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">    run_service</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">/sbin/service</span><span style="color:#C3E88D;"> --status-all </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">grep</span><span style="color:#C3E88D;"> -E </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">running</span><span style="color:#89DDFF;">&quot;)</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;font-style:italic;">fi</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">cat</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#C3E88D;">【服务信息】</span></span>
<span class="line"><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">service_config</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">  </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">line</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">运行的服务:</span></span>
<span class="line"><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">run_service</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">  </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">line</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">监听端口:</span></span>
<span class="line"><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">port_listen</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">  </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">line</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">内核参考配置:</span></span>
<span class="line"><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">kernel_config</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 获取系统内存信息</span></span>
<span class="line"><span style="color:#82AAFF;">get_mem_info</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  check_mem</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">free</span><span style="color:#C3E88D;"> -m</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  MemTotal</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">grep</span><span style="color:#C3E88D;"> MemTotal /proc/meminfo </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">awk</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">{print $2}</span><span style="color:#89DDFF;">&#39;)</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">#KB</span></span>
<span class="line"><span style="color:#A6ACCD;">  MemFree</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">grep</span><span style="color:#C3E88D;"> MemFree /proc/meminfo </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">awk</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">{print $2}</span><span style="color:#89DDFF;">&#39;)</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">#KB</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">let</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">MemUsed=MemTotal-MemFree</span></span>
<span class="line"><span style="color:#A6ACCD;">  MemPercent</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">awk</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">BEGIN {if(</span><span style="color:#A6ACCD;">$MemTotal</span><span style="color:#C3E88D;">==0){printf 100}else{printf </span><span style="color:#A6ACCD;">\&quot;</span><span style="color:#C3E88D;">%.2f</span><span style="color:#A6ACCD;">\&quot;</span><span style="color:#C3E88D;">,</span><span style="color:#A6ACCD;">$MemUsed</span><span style="color:#C3E88D;">*100/</span><span style="color:#A6ACCD;">$MemTotal</span><span style="color:#C3E88D;">}}</span><span style="color:#89DDFF;">&quot;)</span></span>
<span class="line"><span style="color:#A6ACCD;">  report_MemTotal</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;$((</span><span style="color:#C3E88D;">MemTotal</span><span style="color:#89DDFF;">/</span><span style="color:#F78C6C;">1024</span><span style="color:#89DDFF;">))&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">&quot;MB&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">#内存总容量(MB)</span></span>
<span class="line"><span style="color:#A6ACCD;">  report_MemFree</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">&quot;$((</span><span style="color:#C3E88D;">MemFree</span><span style="color:#89DDFF;">/</span><span style="color:#F78C6C;">1024</span><span style="color:#89DDFF;">))&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">&quot;MB&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;">#内存剩余(MB)</span></span>
<span class="line"><span style="color:#A6ACCD;">  report_MemUsedPercent</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">free</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">sed</span><span style="color:#C3E88D;"> -n </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">2p</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">gawk</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">x = int(( $3 / $2 ) * 100) {print x}</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">sed</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">s/$/%/</span><span style="color:#89DDFF;">&#39;)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">cat</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#C3E88D;">【内存信息】</span></span>
<span class="line"><span style="color:#C3E88D;">内存总容量(MB): </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">report_MemTotal</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">内存剩余量(MB):</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">report_MemFree</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">内存使用率: </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">report_MemUsedPercent</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 获取系统网络信息</span></span>
<span class="line"><span style="color:#82AAFF;">get_net_info</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  pri_ipadd</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">ip</span><span style="color:#C3E88D;"> addr </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">awk</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">/^[0-9]+: / {}; /inet.*global/ {print gensub(/(.*)\/(.*)/, &quot;\\1&quot;, &quot;g&quot;, $2)}</span><span style="color:#89DDFF;">&#39;)</span></span>
<span class="line"><span style="color:#A6ACCD;">  pub_ipadd</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">curl</span><span style="color:#C3E88D;"> ifconfig.me -s</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  gateway</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">ip</span><span style="color:#C3E88D;"> route </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">grep</span><span style="color:#C3E88D;"> default </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">awk</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">{print $3}</span><span style="color:#89DDFF;">&#39;)</span></span>
<span class="line"><span style="color:#A6ACCD;">  mac_info</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">ip</span><span style="color:#C3E88D;"> link </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">egrep</span><span style="color:#C3E88D;"> -v </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">lo</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">grep</span><span style="color:#C3E88D;"> link </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">awk</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">{print $2}</span><span style="color:#89DDFF;">&#39;)</span></span>
<span class="line"><span style="color:#A6ACCD;">  dns_config</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">egrep</span><span style="color:#C3E88D;"> -v </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">^$|^#</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> /etc/resolv.conf</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  route_info</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">route</span><span style="color:#C3E88D;"> -n</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">cat</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#C3E88D;">【网络信息】</span></span>
<span class="line"><span style="color:#C3E88D;">系统公网地址:</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">pub_ipadd</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">系统私网地址:</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">pri_ipadd</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">网关地址:</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">gateway</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">MAC地址:</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">mac_info</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">路由信息:</span></span>
<span class="line"><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">route_info</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">DNS 信息:</span></span>
<span class="line"><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">dns_config</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 获取系统磁盘信息</span></span>
<span class="line"><span style="color:#82AAFF;">get_disk_info</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  disk_info</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">fdisk</span><span style="color:#C3E88D;"> -l </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">grep</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">Disk /dev</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">cut</span><span style="color:#C3E88D;"> -d, -f1</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  disk_use</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">df</span><span style="color:#C3E88D;"> -hTP </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">awk</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">$2!=&quot;tmpfs&quot;{print}</span><span style="color:#89DDFF;">&#39;)</span></span>
<span class="line"><span style="color:#A6ACCD;">  disk_percent</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">free</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">sed</span><span style="color:#C3E88D;"> -n </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">2p</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">gawk</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">x = int(( $3 / $2 ) * 100) {print x}</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">sed</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">s/$/%/</span><span style="color:#89DDFF;">&#39;)</span></span>
<span class="line"><span style="color:#A6ACCD;">  disk_inode</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">df</span><span style="color:#C3E88D;"> -hiP </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">awk</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">$1!=&quot;tmpfs&quot;{print}</span><span style="color:#89DDFF;">&#39;)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">cat</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#C3E88D;">【磁盘信息】</span></span>
<span class="line"><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">disk_info</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">磁盘使用: </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">disk_use</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">磁盘使用百分比: </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">disk_percent</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">inode信息: </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">disk_inode</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 获取系统用户信息</span></span>
<span class="line"><span style="color:#82AAFF;">get_sys_user</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  login_user</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">awk</span><span style="color:#C3E88D;"> -F: </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">{if ($NF==&quot;/bin/bash&quot;) print $0}</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;"> /etc/passwd</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  ssh_config</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">egrep</span><span style="color:#C3E88D;"> -v </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">^#|^$</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> /etc/ssh/sshd_config</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  sudo_config</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">egrep</span><span style="color:#C3E88D;"> -v </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">^#|^$</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> /etc/sudoers </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">grep</span><span style="color:#C3E88D;"> -v </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">^Defaults</span><span style="color:#89DDFF;">&quot;)</span></span>
<span class="line"><span style="color:#A6ACCD;">  host_config</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">egrep</span><span style="color:#C3E88D;"> -v </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">^#|^$</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> /etc/hosts</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  crond_config</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#C3E88D;">for cronuser </span><span style="color:#89DDFF;font-style:italic;">in</span><span style="color:#C3E88D;"> /var/spool/cron/</span><span style="color:#89DDFF;">*;</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;font-style:italic;">do</span></span>
<span class="line"><span style="color:#C3E88D;">    </span><span style="color:#FFCB6B;">ls</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">cronuser</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">2&gt;</span><span style="color:#C3E88D;"> /dev/null </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">cut</span><span style="color:#C3E88D;"> -d/ -f5</span><span style="color:#89DDFF;">;</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">egrep</span><span style="color:#C3E88D;"> -v </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">^$|^#</span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">cronuser</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">2&gt;</span><span style="color:#C3E88D;"> /dev/null</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#C3E88D;">    </span><span style="color:#82AAFF;">echo</span><span style="color:#C3E88D;"> </span><span style="color:#89DDFF;">&quot;&quot;;</span></span>
<span class="line"><span style="color:#C3E88D;">  done</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">cat</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#C3E88D;">【用户信息】</span></span>
<span class="line"><span style="color:#C3E88D;">系统登录用户:</span></span>
<span class="line"><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">login_user</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">  </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">line</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">ssh 配置信息:</span></span>
<span class="line"><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">ssh_config</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">  </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">line</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">sudo 配置用户:</span></span>
<span class="line"><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">sudo_config</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">  </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">line</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">定时任务配置:</span></span>
<span class="line"><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">crond_config</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">  </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">line</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">hosts 信息:</span></span>
<span class="line"><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">host_config</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;"># 获取CPU/内存占用TOP10</span></span>
<span class="line"><span style="color:#82AAFF;">get_process_top_info</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">  top_title</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">top</span><span style="color:#C3E88D;"> -b n1 </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">head</span><span style="color:#C3E88D;"> -7 </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">tail</span><span style="color:#C3E88D;"> -1</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  cpu_top10</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">top</span><span style="color:#C3E88D;"> -b n1 </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">head</span><span style="color:#C3E88D;"> -17 </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">tail</span><span style="color:#C3E88D;"> -11</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">  mem_top10</span><span style="color:#89DDFF;">=</span><span style="color:#89DDFF;">$(</span><span style="color:#FFCB6B;">top</span><span style="color:#C3E88D;"> -b n1 </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">head</span><span style="color:#C3E88D;"> -17 </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">tail</span><span style="color:#C3E88D;"> -10 </span><span style="color:#89DDFF;">|</span><span style="color:#C3E88D;"> </span><span style="color:#FFCB6B;">sort</span><span style="color:#C3E88D;"> -k10 -r</span><span style="color:#89DDFF;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">cat</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&lt;&lt;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#C3E88D;">【TOP10】</span></span>
<span class="line"><span style="color:#C3E88D;">CPU占用TOP10:</span></span>
<span class="line"><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">cpu_top10</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">内存占用TOP10:</span></span>
<span class="line"><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">top_title</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#C3E88D;">  </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">mem_top10</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">EOF</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">show_dead_process</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">僵尸进程：\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">ps</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-al</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">|</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">gawk</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">{print $2,$4}</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">|</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">grep</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">Z</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">get_all_info</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">get_systatus_info</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">double_line</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">get_service_info</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">double_line</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">get_cpu_info</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">double_line</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">get_net_info</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">double_line</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">get_mem_info</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">double_line</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">get_disk_info</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">double_line</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">get_process_top_info</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">double_line</span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#FFCB6B;">get_sys_user</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#82AAFF;">main</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;font-style:italic;">while</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[[</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">]]</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;font-style:italic;">do</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#FFCB6B;">printMenu</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#82AAFF;">read</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">option</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#C792EA;">local</span><span style="color:#A6ACCD;"> index</span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;">$</span><span style="color:#C3E88D;">[</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">option</span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">]</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">case</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">options</span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">${index}</span><span style="color:#89DDFF;">]}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;font-style:italic;">in</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">获取系统信息</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">get_systatus_info</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">;;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">获取服务信息</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">get_service_info</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">;;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">获取CPU信息</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">get_cpu_info</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">;;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">获取系统网络信息</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">get_net_info</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">;;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">获取系统内存信息</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">get_mem_info</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">;;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">获取系统磁盘信息</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">get_disk_info</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">;;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">获取CPU/内存占用TOP10</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">get_process_top_info</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">;;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">获取系统用户信息</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">get_sys_user</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">;;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">输出所有信息</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">get_all_info</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&gt;</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">sys.log</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;${</span><span style="color:#A6ACCD;">C_GREEN</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">信息已经输出到 sys.log 中。</span><span style="color:#89DDFF;">${</span><span style="color:#A6ACCD;">C_RESET</span><span style="color:#89DDFF;">}</span><span style="color:#C3E88D;">\n\n</span><span style="color:#89DDFF;">&quot;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">;;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">退出</span><span style="color:#89DDFF;">&quot;</span><span style="color:#89DDFF;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#82AAFF;">exit</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">;;</span></span>
<span class="line"><span style="color:#A6ACCD;">      </span><span style="color:#89DDFF;">*)</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#FFCB6B;">clear</span></span>
<span class="line"><span style="color:#A6ACCD;">        </span><span style="color:#82AAFF;">echo</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;</span><span style="color:#C3E88D;">抱歉，不支持此选项</span><span style="color:#89DDFF;">&quot;</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">;;</span></span>
<span class="line"><span style="color:#A6ACCD;">    </span><span style="color:#89DDFF;font-style:italic;">esac</span></span>
<span class="line"><span style="color:#A6ACCD;">  </span><span style="color:#89DDFF;font-style:italic;">done</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#676E95;font-style:italic;">######################################## MAIN ########################################</span></span>
<span class="line"><span style="color:#FFCB6B;">printHeadInfo</span></span>
<span class="line"><span style="color:#FFCB6B;">main</span></span>
<span class="line"><span style="color:#FFCB6B;">printFootInfo</span></span>
<span class="line"><span style="color:#82AAFF;">printf</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">&quot;${</span><span style="color:#A6ACCD;">C_RESET</span><span style="color:#89DDFF;">}&quot;</span></span></code></pre></div><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2022.6.30/202207052252281.png" alt="image-20220705225247078" style="zoom:67%;"><h1 id="linux5种io模型" tabindex="-1">Linux5种IO模型 <a class="header-anchor" href="#linux5种io模型" aria-label="Permalink to &quot;Linux5种IO模型&quot;">​</a></h1><p>大家好，我是老三，人生有三大难题，事业、爱情，和——这顿吃什么！人在家中躺，肚子饿得响，又到了不得不吃的时候，这顿饭该怎么吃？吃什么呢？Linux里有五种IO模型：<code>阻塞IO</code>、<code>非阻塞IO</code>、<code>多路复用IO</code>、<code>信号驱动式IO</code>和<code>异步IO</code>，我发现这五种IO模型，其实能和吃饭这件事关联起来。</p><h2 id="阻塞io-blocking-i-o" tabindex="-1">阻塞IO（Blocking I/O） <a class="header-anchor" href="#阻塞io-blocking-i-o" aria-label="Permalink to &quot;阻塞IO（Blocking I/O）&quot;">​</a></h2><blockquote><p>阻塞IO是最常见的IO模型。当发起一个IO操作时，比如读取数据，系统会调用read()函数。如果请求的数据没有准备好，此时进程会被挂起（blocked），进入等待状态。直到数据准备好，而且复制到应用进程的缓冲区，这时候才会返回。从调用到返回，整个时间段都是阻塞的，所以被称为阻塞IO。</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305111700765.png" alt="image-20230511170025666" style="zoom:67%;"><p>就像是手机没电的时候，去饭馆吃饭，我点完菜，只能等着厨师做好，服务员端上来，我才能愉快干饭。这段时间，我就只能坐在座位上干等。</p><h2 id="非阻塞io-non-blocking-i-o" tabindex="-1">非阻塞IO（Non-Blocking I/O） <a class="header-anchor" href="#非阻塞io-non-blocking-i-o" aria-label="Permalink to &quot;非阻塞IO（Non-Blocking I/O）&quot;">​</a></h2><blockquote><p>阻塞IO，还是比较浪费资源的，那么非阻塞IO就来了。所谓非阻塞IO，是在调用IO操作时，如果缓冲区没有数据的话，直接返回一个错误码。应用进程需要不断轮询，来检查数据是否准备好。数据准备好了，就返回数据。</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305111701764.png" alt="image-20230511170116662" style="zoom:67%;"><blockquote><p>就像是我奢侈一把，想吃个西餐，于是就去了肯德基，点完餐，我就可以坐着刷刷手机。当然，我还需要时不时地看看我的餐是不是已经备好，餐备好了，就去取一下。</p></blockquote><h2 id="多路复用io-i-o-multiplexing" tabindex="-1">多路复用IO（I/O Multiplexing） <a class="header-anchor" href="#多路复用io-i-o-multiplexing" aria-label="Permalink to &quot;多路复用IO（I/O Multiplexing）&quot;">​</a></h2><blockquote><p>虽然非阻塞IO相比阻塞IO，性能提升了很多，但是轮询过程中，还是有大量的系统调用，上下文切换的开销比较大。那么，多路复用IO就来了。</p></blockquote><blockquote><p>多路指的是多个数据通道，复用指的是一个进程可以同时监控多个文件描述符（比如socket），当某个文件描述符状态发生变化（比如变得可读或可写），多路复用的函数将返回变化的文件描述符。这样，在数据传输过程中，同一个进程中不同的任务都能被处理。特点是在数据传输过程中，进程能够同时处理多个任务，提高了程序的效率。</p></blockquote><blockquote><p>select、poll、epoll 等都是 I/O 多路复用的具体实现。以select/poll为例，进程通过将一个或多个fd传递给select或poll系统调用，阻塞在select操作上，这样select/poll可以侦测多个fd是否处于就绪状态。当有fd就绪时，立即回调函数rollback，接下来就可以进行读取。</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305111701595.png" alt="image-20230511170141482" style="zoom:67%;"><blockquote><p>就像是我想吃顿好的，于是选择去吃自助餐，自助餐有很多餐区，我先看看哪个餐区有我想吃的菜，然后端着盘子去取就行了，一个人就可以取多个菜，肉、蔬菜、水果，什么都能吃一点，而且不用怎么等。</p></blockquote><h2 id="信号驱动式io-signal-driven-i-o" tabindex="-1">信号驱动式IO（Signal-Driven I/O） <a class="header-anchor" href="#信号驱动式io-signal-driven-i-o" aria-label="Permalink to &quot;信号驱动式IO（Signal-Driven I/O）&quot;">​</a></h2><blockquote><p>信号驱动式IO利用信号机制来进行数据传输。进程首先告诉内核，当数据准备好时，请发送一个SIGIO信号。进程继续执行其他任务，等到收到信号后，再开始进行数据传输。</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305111702900.png" alt="image-20230511170240797" style="zoom:67%;"><blockquote><p>就像是我去吃饭，外带，跟服务员打声招呼，餐好了通知我，这时候我就可以去干其它事情，餐备好之后，服务员通知我，我取餐就行了。</p></blockquote><h2 id="异步io-asynchronous-i-o" tabindex="-1">异步IO（Asynchronous I/O） <a class="header-anchor" href="#异步io-asynchronous-i-o" aria-label="Permalink to &quot;异步IO（Asynchronous I/O）&quot;">​</a></h2><blockquote><p>异步IO是指当发起一个IO操作后，系统会立即返回。异步IO操作在后台进行数据传输，数据传输完成后，系统将通知进程。这样，在整个数据传输的过程中，进程都可以执行其他任务，不需要等待。</p></blockquote><img src="https://edu-8673.oss-cn-beijing.aliyuncs.com/img2023.3.30/202305111704812.png" alt="image-20230511170451708" style="zoom:67%;"><blockquote><p>就像是准备吃饭了，我自己懒得动，直接在某团上点个餐，点完之后爱干啥干啥，等着快递小哥给我送到就行了。</p></blockquote></div></div></main><footer class="VPDocFooter" data-v-6b87e69f data-v-37656e44><!--[--><!--]--><!----><nav class="prev-next" data-v-37656e44><div class="pager" data-v-37656e44><a class="pager-link prev" href="/notebook/Linux/Linux%E5%9F%BA%E7%A1%80.html" data-v-37656e44><span class="desc" data-v-37656e44>Previous page</span><span class="title" data-v-37656e44>Linux基础</span></a></div><div class="pager" data-v-37656e44><a class="pager-link next" href="/notebook/Linux/Shell.html" data-v-37656e44><span class="desc" data-v-37656e44>Next page</span><span class="title" data-v-37656e44>Shell脚本</span></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><!----><!--[--><!--]--></div></div>
    <script>window.__VP_HASH_MAP__=JSON.parse("{\"2、数据库_mysql_mysql面试_基础.md\":\"40da680a\",\"1、学前端_5、小程序_小程序项目.md\":\"60a1629b\",\"1、学前端_4、node_知识篇.md\":\"a7fb500e\",\"1、学前端_2、js_ts_es6 进阶.md\":\"6d07ba10\",\"1、学前端_3、vue_vue3_vue3进阶.md\":\"7ac622b4\",\"5、运维_jenkins.md\":\"929081f8\",\"1、学前端_2、js_ts_typescript.md\":\"875a4aa4\",\"2、数据库_mysql_mysql核心_设计.md\":\"7faf46d1\",\"2、数据库_mysql_mysql核心_基础.md\":\"d8e97f3e\",\"1、学前端_1、html_css_html基础.md\":\"7584d076\",\"1、学前端_5、专题篇_问题篇.md\":\"e893aaa2\",\"2、数据库_mysql_mysql面试_进阶.md\":\"f934806d\",\"3、springboot_运维_原理.md\":\"f4a39db6\",\"2、数据库_influxdb.md\":\"6e1711e1\",\"3、springboot_新特性.md\":\"cdf3e307\",\"mybatis_mybatisplus_jpa.md\":\"8e41681b\",\"1、学前端_5、小程序_小程序优化.md\":\"a2185198\",\"2、数据库_redis_redis基础.md\":\"856df0e0\",\"linux_实用脚本.md\":\"f2299dd5\",\"4、微服务_必备_分布式基础.md\":\"d49863d5\",\"2、数据库_redis_redis优化.md\":\"e66ae32f\",\"4、微服务_springsecurity_进阶篇.md\":\"235a8e9e\",\"5、运维_chatgpt.md\":\"10db3823\",\"2、数据库_mysql_分库分表.md\":\"e1c8a095\",\"start.md\":\"9bc1ff8d\",\"5、运维_github.md\":\"2ec6c735\",\"java学前端_css.md\":\"f11b47f0\",\"1、学前端_5、专题篇_知识篇.md\":\"a463ed8d\",\"linux_软件部署.md\":\"d6722925\",\"2、数据库_neo4j.md\":\"97ad22ac\",\"team.md\":\"ce467a6a\",\"nginx_实战篇.md\":\"7785486e\",\"index.md\":\"8c3ec167\",\"计算机基础_计算机网络_网络基础.md\":\"7a54a85d\",\"1、学前端_4、node_进阶篇.md\":\"60f6db69\",\"java_java集合.md\":\"a049b313\",\"1、学前端_3、vue_vue3_vue3高级.md\":\"614d1516\",\"1、学前端_5、小程序_微信小程序.md\":\"9a4be771\",\"5、运维_netty.md\":\"12ca0278\",\"2、数据库_mysql_mysql核心_运维.md\":\"83f97c16\",\"idea_vs code.md\":\"afdcb593\",\"java学前端_vue3_组件.md\":\"1086884e\",\"idea_chrome.md\":\"4a32afbc\",\"云原生_k8s.md\":\"db58e65a\",\"2、数据库_mysql_mysql核心_进阶.md\":\"61d16dff\",\"ssm_springbatch.md\":\"f799ab4a\",\"三高_分布式.md\":\"db1b8a1b\",\"2、数据库_elasticsearch_1、es基础.md\":\"04d17448\",\"linux_linux基础.md\":\"4b0bf394\",\"idea_idea插件.md\":\"fa86e45a\",\"可视化 _ 监控_可视化大屏.md\":\"004553bd\",\"2、数据库_mongodb_整合.md\":\"3c47d7f4\",\"4、微服务_springsecurity_基础篇.md\":\"534a3401\",\"4、微服务_进阶.md\":\"69095c58\",\"计算机基础_计算机基础_操作系统.md\":\"0f75d113\",\"可视化 _ 监控_zabbix.md\":\"71f2270e\",\"nginx_基础篇.md\":\"c7d8bb50\",\"1、学前端_4、node_项目实战.md\":\"bc5065b8\",\"2、数据库_redis_redis原理.md\":\"5cedf685\",\"可视化 _ 监控_监控基础.md\":\"ac56ce4d\",\"三高_高并发.md\":\"ea9ffc99\",\"2、数据库_redis_redis高级.md\":\"1d5872f6\",\"1、学前端_4、node_基础篇.md\":\"581cc13a\",\"2、数据库_mongodb_基础.md\":\"fb7a0a29\",\"idea_idea基础.md\":\"6f2f9638\",\"4、微服务_必备_sentinel.md\":\"2edfbf6c\",\"2、数据库_elasticsearch_3、es高级.md\":\"ef146606\",\"1、学前端_3、vue_vue3_vue3新语法.md\":\"8afd5409\",\"消息中间件_canal.md\":\"3949163c\",\"ssm_maven.md\":\"2c5e12ed\",\"4、微服务_springsecurity_高级篇.md\":\"882d3ff3\",\"linux_linux进阶.md\":\"188ef7b4\",\"计算机基础_设计模式_uml.md\":\"634ba256\",\"计算机基础_算法_leetcode.md\":\"77162fb9\",\"项目实战_小兔鲜_进阶篇1.md\":\"17c52c81\",\"1、学前端_2、js_ts_es6 基础.md\":\"fda3f18b\",\"项目实战_小兔鲜_进阶篇2.md\":\"a0f23006\",\"软件测试_测试基础.md\":\"8c1060cd\",\"2、数据库_redis_本地缓存.md\":\"00617fe6\",\"nginx_面试篇.md\":\"e3fb373a\",\"mybatis_mybatisplus_mybatis.md\":\"9239e0ad\",\"linux_shell.md\":\"ae53d83b\",\"2、数据库_mysql_mysql核心_优化.md\":\"36230425\",\"项目实战_项目推荐.md\":\"f9d97630\",\"mybatis_mybatisplus_mybatisplus.md\":\"0030fd35\",\"项目实战_百度地图_进阶篇.md\":\"c8b93267\",\"三高_高可用.md\":\"323840c5\",\"java_java新特性.md\":\"22abf56d\",\"软件测试_压力测试.md\":\"9ab44440\",\"java学前端_html_js.md\":\"e0fcd240\",\"2、数据库_redis_redis实战.md\":\"d6daeeab\",\"nginx_进阶篇.md\":\"e6b63195\",\"三高_秒杀.md\":\"3878bb64\",\"5、运维_git.md\":\"0264925c\",\"java_java进阶.md\":\"e79cb5b4\",\"并发 _ 多线程_基础篇.md\":\"7adbfac5\",\"项目实战_百度地图_基础篇.md\":\"8afa5954\",\"java学前端_react.md\":\"3ec827dd\",\"1、学前端_1、html_css_css基础.md\":\"01b56712\",\"项目实战_小兔鲜_基础篇.md\":\"646f5df5\",\"1、学前端_2、js_ts_js 基础.md\":\"cb13e36f\",\"可视化 _ 监控_监控进阶.md\":\"0cdbc292\",\"计算机基础_设计模式_基础篇.md\":\"51617287\",\"计算机基础_数据结构_基础篇.md\":\"b2bfd8d4\",\"项目实战_苍穹外卖_进阶篇.md\":\"48415e41\",\"ssm_spring.md\":\"ab514659\",\"消息中间件_rabbitmq.md\":\"45b1eb28\",\"1、学前端_1、html_css_网页进阶.md\":\"db998248\",\"消息中间件_kafka.md\":\"b747dabf\",\"云原生_docker.md\":\"983c7ba7\",\"4、微服务_必备_分布式锁.md\":\"5af1cf8d\",\"消息中间件_rocketmq.md\":\"d441da85\",\"项目实战_黑马头条_基础篇.md\":\"b05af3a6\",\"ssm_springmvc.md\":\"81b9714f\",\"项目实战_支付.md\":\"1d7407dd\",\"项目实战_黑马头条_进阶篇2.md\":\"bff0015b\",\"项目实战_黑马头条_进阶篇.md\":\"19f18388\",\"java学前端_vue2_组件.md\":\"58c6b1df\",\"3、springboot_基础篇.md\":\"529c66f4\",\"3、springboot_应用篇.md\":\"8b92aa61\",\"项目实战_黑马头条_高级篇.md\":\"227c08c1\",\"1、学前端_5、小程序_uniapp.md\":\"71a282b4\",\"项目实战_云尚办公_基础篇.md\":\"1fe188ba\",\"并发 _ 多线程_并发完善.md\":\"26619c46\",\"1、学前端_2、js_ts_js 进阶.md\":\"657dfb8f\",\"java_java高级.md\":\"23782d1a\",\"java_java基础.md\":\"86d67c77\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"VitePress\",\"description\":\"A VitePress site\",\"base\":\"/notebook/\",\"head\":[],\"appearance\":true,\"themeConfig\":{\"algolia\":{\"appId\":\"DW7O63I9IR\",\"apiKey\":\"f8ed758cdb288a8b06542bc35923c1a1\",\"indexName\":\"notebook\"},\"sidebar\":[{\"text\":\"Java\",\"collapsed\":true,\"items\":[{\"text\":\"Java基础\",\"link\":\"/Java/Java基础\"},{\"text\":\"Java新特性\",\"link\":\"/Java/Java新特性\"},{\"text\":\"Java进阶\",\"link\":\"/Java/Java进阶\"},{\"text\":\"Java集合\",\"link\":\"/Java/Java集合\"},{\"text\":\"Java高级\",\"link\":\"/Java/Java高级\"}]},{\"text\":\"Linux\",\"collapsed\":true,\"items\":[{\"text\":\"Linux基础\",\"link\":\"/Linux/Linux基础\"},{\"text\":\"Linux新特性\",\"link\":\"/Linux/Linux进阶\"},{\"text\":\"Shell脚本\",\"link\":\"/Linux/Shell\"},{\"text\":\"实用脚本\",\"link\":\"/Linux/实用脚本\"},{\"text\":\"软件部署\",\"link\":\"/Linux/软件部署\"}]},{\"text\":\"Nginx\",\"collapsed\":true,\"items\":[{\"text\":\"基础篇\",\"link\":\"/Nginx/基础篇\"},{\"text\":\"进阶篇\",\"link\":\"/Nginx/进阶篇\"},{\"text\":\"实战篇\",\"link\":\"/Nginx/实战篇\"},{\"text\":\"面试篇\",\"link\":\"/Nginx/面试篇\"}]},{\"text\":\"SSM\",\"collapsed\":true,\"items\":[{\"text\":\"Maven\",\"link\":\"/SSM/Maven\"},{\"text\":\"Spring\",\"link\":\"/SSM/Spring\"},{\"text\":\"SpringMVC\",\"link\":\"/SSM/SpringMVC\"},{\"text\":\"SpringBatch\",\"link\":\"/SSM/SpringBatch\"}]},{\"text\":\"SpringBoot\",\"collapsed\":true,\"items\":[{\"text\":\"基础篇\",\"link\":\"/3、SpringBoot/基础篇\"},{\"text\":\"应用篇\",\"link\":\"/3、SpringBoot/应用篇\"},{\"text\":\"新特性\",\"link\":\"/3、SpringBoot/新特性\"},{\"text\":\"运维&原理\",\"link\":\"/3、SpringBoot/运维&原理\"}]},{\"text\":\"SpringCloud\",\"collapsed\":true,\"items\":[{\"text\":\"SpringCloud\",\"link\":\"/4、微服务/进阶\"},{\"text\":\"Sentinel\",\"link\":\"/4、微服务/必备/Sentinel\"}]},{\"text\":\"SpringSecurity\",\"collapsed\":true,\"items\":[{\"text\":\"SpringSecurity基础篇\",\"link\":\"/4、微服务/SpringSecurity/基础篇\"},{\"text\":\"SpringSecurity进阶篇\",\"link\":\"/4、微服务/SpringSecurity/进阶篇\"},{\"text\":\"SpringSecurity高级篇\",\"link\":\"/4、微服务/SpringSecurity/高级篇\"}]},{\"text\":\"Mybatis & MybatisPlus\",\"collapsed\":true,\"items\":[{\"text\":\"Mybatis\",\"link\":\"/Mybatis&MybatisPlus/Mybatis\"},{\"text\":\"MybatisPlus\",\"link\":\"/Mybatis&MybatisPlus/MybatisPlus\"},{\"text\":\"JPA\",\"link\":\"/Mybatis&MybatisPlus/JPA\"}]},{\"text\":\"Git & ChatGPT\",\"collapsed\":true,\"items\":[{\"text\":\"Git\",\"link\":\"/5、运维/Git\"},{\"text\":\"Github\",\"link\":\"/5、运维/Github\"},{\"text\":\"ChatGPT\",\"link\":\"/5、运维/ChatGPT\"},{\"text\":\"Jenkins\",\"link\":\"/5、运维/Jenkins\"},{\"text\":\"Netty\",\"link\":\"/5、运维/Netty\"}]},{\"text\":\"数据库\",\"collapsed\":true,\"items\":[{\"text\":\"MySQL\",\"collapsed\":true,\"items\":[{\"text\":\"MySQL基础\",\"link\":\"/2、数据库/MySQL/MySQL核心/基础\"},{\"text\":\"MySQL进阶\",\"link\":\"/2、数据库/MySQL/MySQL核心/进阶\"},{\"text\":\"MySQL优化\",\"link\":\"/2、数据库/MySQL/MySQL核心/优化\"},{\"text\":\"MySQL设计\",\"link\":\"/2、数据库/MySQL/MySQL核心/设计\"},{\"text\":\"MySQL运维\",\"link\":\"/2、数据库/MySQL/MySQL核心/运维\"},{\"text\":\"分库分表\",\"link\":\"/2、数据库/MySQL/分库分表\"}]},{\"text\":\"Redis\",\"collapsed\":true,\"items\":[{\"text\":\"Redis基础\",\"link\":\"/2、数据库/Redis/Redis基础\"},{\"text\":\"Redis优化\",\"link\":\"/2、数据库/Redis/Redis优化\"},{\"text\":\"Redis原理\",\"link\":\"/2、数据库/Redis/Redis原理\"},{\"text\":\"Redis高级\",\"link\":\"/2、数据库/Redis/Redis高级\"},{\"text\":\"Redis实战\",\"link\":\"/2、数据库/Redis/Redis实战\"},{\"text\":\"本地缓存\",\"link\":\"/2、数据库/Redis/本地缓存\"}]},{\"text\":\"MongoDB\",\"collapsed\":true,\"items\":[{\"text\":\"MongoDB基础\",\"link\":\"/2、数据库/MongoDB/基础\"},{\"text\":\"MongoDB进阶\",\"link\":\"/2、数据库/MongoDB/整合\"}]},{\"text\":\"ElasticSearch\",\"collapsed\":true,\"items\":[{\"text\":\"ES基础\",\"link\":\"/2、数据库/ElasticSearch/1、ES基础\"},{\"text\":\"ES高级\",\"link\":\"/2、数据库/ElasticSearch/3、ES高级\"}]},{\"text\":\"InfluxDB\",\"link\":\"/2、数据库/influxdb\"},{\"text\":\"Neo4j\",\"link\":\"/2、数据库/Neo4j\"}]},{\"text\":\"高并发 & 秒杀 & 分布式\",\"collapsed\":true,\"items\":[{\"text\":\"分布式理论\",\"link\":\"/三高/分布式\"},{\"text\":\"分布式锁\",\"link\":\"/4、微服务/必备/分布式锁\"},{\"text\":\"秒杀\",\"link\":\"/三高/秒杀\"},{\"text\":\"高可用\",\"link\":\"/三高/高可用\"},{\"text\":\"高并发\",\"link\":\"/三高/高并发\"}]},{\"text\":\"云原生\",\"collapsed\":true,\"items\":[{\"text\":\"Docker\",\"link\":\"/云原生/Docker\"},{\"text\":\"K8S\",\"link\":\"/云原生/K8S\"}]},{\"text\":\"可视化 & 监控\",\"collapsed\":true,\"items\":[{\"text\":\"监控基础\",\"link\":\"/可视化 & 监控/监控基础\"},{\"text\":\"监控进阶\",\"link\":\"/可视化 & 监控/监控进阶\"},{\"text\":\"可视化大屏\",\"link\":\"/可视化 & 监控/可视化大屏\"},{\"text\":\"Zabbix\",\"link\":\"/可视化 & 监控/Zabbix\"}]},{\"text\":\"学前端\",\"collapsed\":true,\"items\":[{\"text\":\"HTML+CSS\",\"collapsed\":true,\"items\":[{\"text\":\"HTML基础\",\"link\":\"/1、学前端/1、HTML+CSS/HTML基础\"},{\"text\":\"CSS基础\",\"link\":\"/1、学前端/1、HTML+CSS/CSS基础\"},{\"text\":\"网页进阶\",\"link\":\"/1、学前端/1、HTML+CSS/网页进阶\"}]},{\"text\":\"JS+TS\",\"collapsed\":true,\"items\":[{\"text\":\"JS基础\",\"link\":\"/1、学前端/2、JS+TS/JS 基础\"},{\"text\":\"JS进阶\",\"link\":\"/1、学前端/2、JS+TS/JS 进阶\"},{\"text\":\"ES6基础\",\"link\":\"/1、学前端/2、JS+TS/ES6 基础\"},{\"text\":\"ES6进阶\",\"link\":\"/1、学前端/2、JS+TS/ES6 进阶\"},{\"text\":\"TS基础\",\"link\":\"/1、学前端/2、JS+TS/TypeScript\"}]},{\"text\":\"NodeJS\",\"collapsed\":true,\"items\":[{\"text\":\"Node基础\",\"link\":\"/1、学前端/4、Node/基础篇\"},{\"text\":\"Node进阶\",\"link\":\"/1、学前端/4、Node/进阶篇\"},{\"text\":\"项目实战\",\"link\":\"/1、学前端/4、Node/项目实战\"}]},{\"text\":\"Vue\",\"collapsed\":true,\"items\":[{\"text\":\"Vue3进阶\",\"link\":\"/1、学前端/3、Vue/Vue3/Vue3进阶\"},{\"text\":\"Vue3高级\",\"link\":\"/1、学前端/3、Vue/Vue3/Vue3高级\"},{\"text\":\"Vue3新语法\",\"link\":\"/1、学前端/3、Vue/Vue3/Vue3新语法\"},{\"text\":\"项目实战\",\"link\":\"/1、学前端/3、Vue/Vue2/Vue2项目\"}]},{\"text\":\"小程序\",\"collapsed\":true,\"items\":[{\"text\":\"小程序基础\",\"link\":\"/1、学前端/5、小程序/微信小程序\"},{\"text\":\"小程序优化\",\"link\":\"/1、学前端/5、小程序/小程序优化\"},{\"text\":\"uniapp\",\"link\":\"/1、学前端/5、小程序/uniapp\"},{\"text\":\"项目实战\",\"link\":\"/1、学前端/5、小程序/小程序项目\"}]}]},{\"text\":\"计算机基础\",\"collapsed\":true,\"items\":[{\"text\":\"数据结构\",\"link\":\"/计算机基础/数据结构/基础篇\"},{\"text\":\"操作系统\",\"link\":\"/计算机基础/计算机基础/操作系统\"},{\"text\":\"设计模式\",\"link\":\"/计算机基础/设计模式/基础篇\"},{\"text\":\"计算机网络\",\"link\":\"/计算机基础/计算机网络/网络基础\"},{\"text\":\"UML\",\"link\":\"/计算机基础/设计模式/UML\"},{\"text\":\"LeetCode\",\"link\":\"/计算机基础/算法/LeetCode\"}]},{\"text\":\"项目实战\",\"collapsed\":true,\"items\":[{\"text\":\"云尚办公\",\"collapsed\":true,\"items\":[{\"text\":\"基础篇\",\"link\":\"/项目实战/云尚办公/基础篇\"}]},{\"text\":\"小兔鲜\",\"collapsed\":true,\"items\":[{\"text\":\"基础篇\",\"link\":\"/项目实战/小兔鲜/基础篇\"},{\"text\":\"进阶篇1\",\"link\":\"/项目实战/小兔鲜/进阶篇1\"},{\"text\":\"进阶篇2\",\"link\":\"/项目实战/小兔鲜/进阶篇2\"}]},{\"text\":\"地图\",\"collapsed\":true,\"items\":[{\"text\":\"基础篇\",\"link\":\"/项目实战/百度地图/基础篇\"},{\"text\":\"进阶篇\",\"link\":\"/项目实战/百度地图/进阶篇\"}]},{\"text\":\"苍穹外卖\",\"collapsed\":true,\"items\":[{\"text\":\"进阶篇\",\"link\":\"/项目实战/苍穹外卖/进阶篇\"}]},{\"text\":\"黑马头条\",\"collapsed\":true,\"items\":[{\"text\":\"基础篇\",\"link\":\"/项目实战/黑马头条/基础篇\"},{\"text\":\"进阶篇\",\"link\":\"/项目实战/黑马头条/进阶篇\"},{\"text\":\"进阶篇2\",\"link\":\"/项目实战/黑马头条/进阶篇2\"},{\"text\":\"高级篇\",\"link\":\"/项目实战/黑马头条/高级篇\"}]},{\"text\":\"支付\",\"link\":\"/项目实战/支付\"},{\"text\":\"项目推荐\",\"link\":\"/项目实战/项目推荐\"}]},{\"text\":\"团队成员\",\"link\":\"/team\"}],\"siteTitle\":\"任硕的文档\",\"logo\":\"/Vue.png\",\"nav\":[{\"text\":\"Java学前端\",\"items\":[{\"items\":[{\"text\":\"HTML+JS\",\"link\":\"/Java学前端/HTML+JS\"},{\"text\":\"CSS\",\"link\":\"/Java学前端/CSS\"},{\"text\":\"Vue2+组件\",\"link\":\"/Java学前端/Vue2+组件\"},{\"text\":\"Vue3+组件\",\"link\":\"/Java学前端/Vue3+组件\"},{\"text\":\"React\",\"link\":\"/Java学前端/React\"}]}],\"activeMatch\":\"/Java/\"},{\"text\":\"软件测试\",\"items\":[{\"items\":[{\"text\":\"测试基础\",\"link\":\"/软件测试/测试基础\"},{\"text\":\"压力测试\",\"link\":\"/软件测试/压力测试\"}]}]},{\"text\":\"多线程\",\"items\":[{\"items\":[{\"text\":\"基础篇\",\"link\":\"/并发 & 多线程/基础篇\"},{\"text\":\"进阶篇\",\"link\":\"/并发 & 多线程/并发完善\"}]}]},{\"text\":\"开发工具\",\"items\":[{\"items\":[{\"text\":\"Chrome\",\"link\":\"/IDEA/Chrome\"},{\"text\":\"IDEA基础\",\"link\":\"/IDEA/IDEA基础\"},{\"text\":\"IDEA插件\",\"link\":\"/IDEA/IDEA插件\"},{\"text\":\"VS Code\",\"link\":\"/IDEA/VS Code\"}]}]},{\"text\":\"消息中间件\",\"items\":[{\"items\":[{\"text\":\"RabbitMQ\",\"link\":\"/消息中间件/RabbitMQ\"},{\"text\":\"RocketMQ\",\"link\":\"/消息中间件/RocketMQ\"},{\"text\":\"Kafka\",\"link\":\"/消息中间件/Kafka\"},{\"text\":\"Canal\",\"link\":\"/消息中间件/Canal\"}]}]}],\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/renshuo123/renshuo123.github.io\"},{\"icon\":\"twitter\",\"link\":\"#\"},{\"icon\":{\"svg\":\"<svg t=\\\"1676028692954\\\" class=\\\"icon\\\" ...</path></svg>\"},\"link\":\"https://github.com/\"}]},\"locales\":{},\"scrollOffset\":90,\"cleanUrls\":false}");</script>
    
  </body>
</html>